2016-01-04 74 views
1

我可以聲明匿名函數(它們是相同的拉姆達,但沒有「背景」 - [...])無auto容易:如何用函數指針(不帶自動)聲明lambda?

#include <iostream> 

using namespace ::std; 

void foo(void (*f)(char)) 
{ 
    f('r'); 
} 

int main() 
{ 
    void (*anon)(char) = [](char c) -> void { cout << c << endl; }; 
    foo(anon); 
    return 0; 
} 

但如何申報拉姆達?這是唯一可能的方式嗎? (也許用typedef)。這裏我用::std::function,但我並沒有在富爭論提到的˚F背景某處...:

#include <iostream> 
#include <functional> 

using namespace ::std; 

//int foo(auto f, char x) // !only since c++14 
int foo(function<int(char)> f, char x) 
{ 
    return f(x+1); 
} 

int main() 
{ 
    int a = 5, b = 10; 

    //void (*lambda)(char) = [](char c) { cout << c << endl; }; 
    //auto sample_lambda = [&a,b](char c) -> int // !only since c++11 
    function<int(char)> sample_lambda = [&a,b](char c) -> int 
     { 
      for (;a<b;a++) 
       cout << a << c << endl; 
      return (int)c+a; 
     }; 

    foo(sample_lambda, 's'); 
    return 0; 
} 
+0

將foo定義爲模板函數。 'template void foo(Function && f){f('r'); }' –

+1

「聲明lambda」沒有意義。拉姆達是一種*表達*類型,你不能去除表達式,只能說,「聲明一個和」或「聲明一個函數調用」。 –

+2

非捕獲的lambda表達式可以衰減爲指向函數的指針,但它*不是指向函數的指針。 –

回答

5

你不能。

閉包的類型是唯一的未命名類型。你的第一個例子是有效的,因爲如果閉包類型沒有捕獲任何東西,閉包類型就有一個指向函數的轉換函數,而不是因爲關閉 a void (*) (char)

你最好只是堅持autostd::function可以有類型擦除額外的開銷。

0

auto作爲參數是由GCC等提供的擴展。你可以做的是使用模板:

template<typename T> 
int callFoo(T funct, int x) { 
    return funct(x+1); 
}