在C ++ 11中用“auto”推导出什么是lambda的types?

我有一个感觉,lambda的types是一个函数指针。 当我进行下面的testing时,我发现它是错误的( 演示 )。

#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 ! } 

上面的代码是否缺less任何一点? 如果不是那么,用auto关键字推导出lambdaexpression式的types是什么?

lambdaexpression式的types是未指定的。

但它们通常只是函子的语法糖。 一个lambda被直接转换成一个函子。 []中的任何内容都变成了构造函数参数和函子对象的成员,并且参数inside ()变成了函子operator()

一个没有捕获variables的lambda 可以被转换成一个函数指针(MSVC2010不支持这个,如果这是你的编译器,但是这个转换是标准的一部分)。

但是lambda的实际types不是函数指针。 这是一些未指定的仿函数types。

这是一个独特的无名结构,重载函数调用操作符。 lambda的每个实例都引入一个新的types。

在非捕获lambda的特殊情况下,该结构还有一个隐式转换为函数指针。

[C++11: 5.1.2/3]: lambdaexpression式 (也是闭包对象的types)的types是唯一的,未命名的非联合类types – 称为闭包types – 其属性是如下面所描述的。 这个类的types不是一个聚合(8.5.1)。 闭包types在包含相应lambdaexpression式的最小块作用域,类作用域或命名空间作用域中声明。 [..]

该条款继续列出这种types的不同属性。 这里有一些亮点:

[C++11: 5.1.2/5]: lambdaexpression式的闭包types有一个公共的inline函数调用操作符(13.5.4),其参数和返回types由lambdaexpression式参数声明- 条款拖尾返回types[..]

[C++11: 5.1.2/6]:没有lambda-capturelambdaexpression式的闭包types有一个公共的非虚拟非显式const转换函数,指向具有相同参数和返回types的函数闭包types的函数调用操作符。 这个转换函数返回的值应该是被调用的函数的地址,和调用闭包types的函数调用操作符一样。

最后一段的结果是,如果你使用了一个转换,你可以把LAMBDA分配给pFptr

如何将一个boost :: bind对象作为类成员存储? ,请尝试boost::function<void(int)>std::function<void(int)>

 #include <iostream> #include <typeinfo> #define LAMBDA [] (int i)->long { return 0l; } int main () { long (*pFptr)(int) = LAMBDA; // ok auto pAuto = LAMBDA; // ok std::cout<<typeid( *pAuto ).name() << std::endl; std::cout<<typeid( *pFptr ).name() << std::endl; std::cout<<typeid( pAuto ).name() << std::endl; std::cout<<typeid( pFptr ).name() << std::endl; } 

函数types确实是一样的,但lambda引入了新的types(如仿函数)。

它也应该注意到,lambda可以转换为函数指针。 然而,typeid <>返回一个非平凡的对象,它应该与lambda到generics函数指针不同。 所以typeid <>的testing不是一个有效的假设。 一般来说,C ++ 11不希望我们担心types规范,只要给定的types可以转换为目标types就行。