У меня было ощущение, что тип лямбда - это указатель на функцию. Когда я выполнил следующий тест, я обнаружил, что это неправильно ( демо ).
#define LAMBDA [] (int i) -> long { return 0; }
int main ()
{
long (*pFptr)(int) = LAMBDA; // ok
auto pAuto = LAMBDA; // ok
assert(typeid(pFptr) == typeid(pAuto)); // assertion fails !
}
Выше кода не хватает какой-либо точки? Если нет, то каково typeof
лямбда-выражение при выводе с auto
ключевым словом?
Ответы:
Тип лямбда-выражения не указан.
Но они, как правило, просто синтаксический сахар для функторов. Лямбда переводится прямо в функтор. Все, что внутри
[]
, превращается в параметры конструктора и члены объекта функтора, а параметры внутри()
превращаются в параметры для функтораoperator()
.Лямбда, которая не содержит переменных (ничего внутри
[]
), может быть преобразована в указатель на функцию (MSVC2010 не поддерживает это, если это ваш компилятор, но это преобразование является частью стандарта).Но фактический тип лямбды не является указателем на функцию. Это некоторый неопределенный тип функтора.
источник
operator()
основном это stackoverflow.com/questions/356950/c-functors-and-their-usesЭто уникальная безымянная структура, которая перегружает оператор вызова функции. Каждый экземпляр лямбды вводит новый тип.
В особом случае не захвата лямбды, структура дополнительно имеет неявное преобразование в указатель на функцию.
источник
type_info::name()
определяется реализацией, поэтому может возвращать что угодно. На практике компилятор назовет тип для компоновщика.Предложение продолжает перечислять различные свойства этого типа. Вот некоторые основные моменты:
Следствием этого последнего отрывка является то, что, если вы использовали преобразование, вы сможете назначить
LAMBDA
дляpFptr
.источник
Типы функций действительно одинаковы, но лямбда вводит новый тип (например, функтор).
источник
__PRETTY_FUNCTION__
, как вtemplate<class T> const char* pretty(T && t) { return __PRETTY_FUNCTION__; }
, и снимаю лишнее, если оно начинает переполняться. Я предпочитаю видеть шаги, показанные при замене шаблона. Если вам не хватает__PRETTY_FUNCTION__
, есть альтернативы для MSVC и т. Д., Но результаты всегда зависят от компилятора по той же причине, по которой необходим CXXABI.Следует также отметить, что лямбда-преобразователь является указателем на функцию. Однако typeid <> возвращает нетривиальный объект, который должен отличаться от лямбды до указателя обобщенной функции. Таким образом, тест для typeid <> не является допустимым предположением. В целом C ++ 11 не хочет, чтобы мы беспокоились о спецификации типа, все это имеет значение, если данный тип может быть преобразован в целевой тип.
источник
Практическое решение из Как я могу сохранить объект boost :: bind в качестве члена класса? , попробуйте
boost::function<void(int)>
илиstd::function<void(int)>
.источник