2014-04-02 50 views
0

我想創建一個既接受函數指針又接受lambda表達式的函數。函數的返回類型應該與函數指針/ lambda表達式的返回類型相同。返回與作爲參數傳遞的lambda表達式相同的類型

以下是一個按預期工作的函數的最小示例,但僅適用於函數指針。我可以使用模板來接受lambda表達式嗎?

template <typename R> 
R foo(R (*func)()) 
{ 
    return func(); 
} 

兩個函數指針和lambda表達式下面的作品,但只接受bool

bool foo(std::function<bool()> func) 
{ 
    return func(); 
} 

bool a = foo([](){ return true; }); 

我試圖使它通用使用的模板,但我得到一個編譯錯誤,當它被稱爲(不匹配功能)

template <typename R> 
R foo(std::function<R()> func) 
{ 
    return func(); 
} 

bool a = foo([](){ return true; }); 
+0

lambda表達式沒有捕捉可以轉化爲函數指針 – sp2danny

+0

@ sp2danny:是的,但前提是你必須爲轉換的上下文。這裏的第一個問題是你不知道它將要轉換的函數指針類型。 – MSalters

回答

5

您可以使用推導的返回類型:

template <typename F> 
auto foo(F f) -> decltype(f()) 
{ 
    return f(); 
} 

如果F需要一些參數:

template <typename F, typename ... Args> 
auto foo(F f, Args&&...args) -> decltype(f(std::forward<Args>(args)...)) 
{ 
    return f(std::forward<Args>(args)...); 
} 
+0

謝謝。該解決方案是否可以擴展以支持將參數傳遞給f? E.g. 'R foo(R(* f)(T),T x){return f(x); }' –

+1

@SamOlesen:是的,解決方案可以擴展爲支持參數:請參閱編輯。 – Jarod42

+0

如果「f」採用未列在「foo」參數列表中的參數,該怎麼辦? – ARA1307

3

這對decltype工作:

template <typename F> 
auto foo(F f) -> decltype(f()) 
{ 
} 
相關問題