簡體   English   中英

C ++ 11中的函數簽名差異

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM