2013-04-09 545 views
0

我有一個過載功能,具有以下簽名功能:C++與lambda表達式作爲參數

void Foo(const std::function<void(int )> &func); 
void Foo(const std::function<void(int, int)> &func); 

當我要與lambda表達式使用美孚(),我必須做這樣的事情:

Foo((std::function<void(int )>) [] (int i  ) { /* do something */ }); 
Foo((std::function<void(int, int)>) [] (int i, int j) { /* do something */ }); 

兩者都不那麼用戶友好。這將會是一個更容易使用的功能,而不具有lambda表達式之前增加鑄造「(STD ::功能< ...>)」 - 這樣的:

Foo([] (int i  ) { /* do something */ }); // executes the 1st Foo() 
    Foo([] (int i, int j) { /* do something */ }); // executes the 2nd Foo() 

所以,我需要另一個重載,接受lambda作爲它的參數,並自動將lambda轉換爲上述簽名之一。如何才能做到這一點?或者,首先有可能嗎?

template <typename Function> void Foo(Function function) { 
    // insert code here: should be something like 
    // - check the signature of the 'function'; and 
    // - call 'Foo()' corresponding to the signature 
} 

請大家幫忙。

PS。我正在使用VS2010。

+0

你使用什麼編譯器,以及什麼版本?順便說一句,在叮噹聲3.3(幹線177501)中工作正常。 – 2013-04-09 05:41:59

+0

我正在使用VS2010。 – hiapay 2013-04-09 06:41:56

回答

3

如果您拉姆達沒有捕獲任何變量,也就是說,它與[]開始 - 那麼它可轉化爲函數指針,你可以聲明Foo像這樣:

void Foo(void(*func)(int)); 
void Foo(void(*func)(int, int)); 

如果你想保留std::function版本,您可以將這些版本轉發到該版本。如果你不想單獨實現這些,我覺得一個可變參數模板將很好地做到:

如果你的lambda表達式捕獲變量,那麼他們無法轉換爲函數指針,你會需要包裝他們自己在std::function

+0

對不起,我沒有提到我使用VS2010,它不允許lambda到函數指針的轉換。我想我將不得不改變我的編譯器或與它一起生活......非常感謝! – hiapay 2013-04-09 06:51:18

1

Lambda隱式轉換爲std :: function <>,不需要顯式轉換。

std::function<void(int, int)> func = [](int a, int b){ printf("Hello Lambda world!"); }; 
func(1, 2); 

啊,你試圖得到一個const引用它。爲什麼?你應該使用右手參考(因爲它是臨時的)或副本。在這兩種情況下,它應該隱式轉換以及...