[英]Function signature differences in C++11
考虑使用以下代码的C ++ 11的lambdas,
template <typename M>
void call(void (*f)(M), M m)
{
f(m);
}
int main()
{
call<int>([](int n) { }, 42); // OK
int r;
call<int>([&](int n) { r = n; }, 42); // KO
}
lambda之间是否存在签名差异,使得第二个与call
的参数不兼容?
我用的是g ++ 4.6.1。
旁边的问题:如果我写call([](int n) { }, 42);
为什么不能推断参数call([](int n) { }, 42);
?
只有无捕获的lambda可以隐式转换为函数指针。
捕获变量的lambda无法转换为函数指针,因为它具有需要维护的状态(捕获的变量),并且该状态不能由函数指针表示。
无法从函数参数推断出类型M
因为需要转换才能将lambda转换为函数指针。 该转换禁止模板参数推断。 如果你用实际函数调用函数call
(例如, void f(int)
),那么参数推导就可以了。
正如詹姆斯已经回答的那样,只有无法捕获的lambdas可以转换为函数指针。 具有状态的Lambdas创建实现operator()
functor对象,并且成员函数指针与自由函数指针不兼容。
编译器处理时: [&](int n){ r = n; }
[&](int n){ r = n; }
它会产生这样的:
class __annonymous_lambda_type {
int & r;
public:
__annonymous_lambda_type( int & r ) : r(r) {}
void operator()( int n ) const {
r = n;
}
} __lambda_instatiation;
该类需要存储lambda的状态,在这种情况下是对执行lambda时将被修改的外部对象的引用。 void operator()(int)
不能绑定到void (*)(int)
。
另一方面,如果lambda是无状态的,它可以实现为自由函数,就像在[]( int n ) { std::cout << "Hi" << n << std::endl ; }
[]( int n ) { std::cout << "Hi" << n << std::endl ; }
void __annonymous_lambda_function( int n ) {
std::cout << "Hi " << n << std::endl;
}
因为lambda根本不需要保持任何状态,因此它可以保持为普通函数。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.