[英]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.