#c #lambda #c 11
#c #лямбда #c 11
Вопрос:
Как мне исправить приведенный ниже код для сохранения лямбда-выражения, чтобы я мог вызвать его позже?
Ошибка, которую я получаю в данный момент, заключается в том, что поле ‘m_callback’ имеет неполный тип.
class Foo
{
public:
Foo() { }
~Foo() { }
template< typename FuncT >
void setCallback( FuncTamp;amp; callback )
{
m_callback = callback;
}
private:
auto m_callback; // this line is broken
};
int main(int argc, char** argv)
{
Foo foo;
foo.setCallback( [] (int x){ return true; } );
return 0;
}
Комментарии:
1.
m_callback = callback;
должно бытьm_callback = std::forward<FuncT>(callback);
Ответ №1:
auto
Ключевое слово can’t be used понравилось. Я рекомендую использовать что-то вроде этого:
#include <functional>
std::function<bool (int)> m_callback;
Это делается из Visual Studio 2010.
Комментарии:
1. хм … … этот ответ хорошо работает, если я заранее знаю сигнатуру лямбда-выражения. Что, если я не знаю сигнатуру (например, я действительно хочу передать void *, который вводится и возвращается позже, но не вызывается внутри Foo)?
2. @kfmfe04: C статически типизирован — вам нужно заранее знать свою подпись. Если вы хотите поддерживать несколько подписей, взгляните на Boost.Variant .
Ответ №2:
auto
Ключевое слово может использоваться только в сочетании с выражением инициализации.
Итак … это работает:
auto callback = [](int x){ return x == 0; };
… но это не:
auto callback;
callback = [](int x){ return x == 0; };
Я бы рекомендовал вам использовать что-то вроде function
с определенной подписью для представления обратного вызова.
Комментарии:
1. Чтобы быть более точным, во втором случае
auto
интерпретируется как спецификатор хранилища , напримерregister
. В старые временаC
,auto
был спецификатором хранилища по умолчанию и означал автоматическое хранение (которое для большинства компиляторов является повсеместным стеком). Конечно, поскольку оно используется по умолчанию… уточнять его было не очень полезно, поэтому оно редко использовалось на практике.2. @MatthieuM.: В C 11,
auto
поскольку спецификатор хранилища полностью удален.3. @GMan: о! Я думал, что оно только устарело: x
4. @MatthieuM.: Нет. Для них, конечно, необычно совершать такой прямой переход, но это просто показывает, как вы говорите, насколько это было бесполезно на самом деле.