2014-01-20 63 views
4

我想寫功能func使編譯器可以推斷出模板參數,就當我通過在std::function工作,但不lambda表達式工作:推斷模板參數時,拉姆達傳過來的參數

template<typename TResult> 
TResult func(std::function<TResult()> f) 
{ 
    return TResult(); 
} 

int main() 
{ 
           // Visual Studio 2013 
    int result = func([]() { // error: 'TResult func(std::function<TResult(void)>)' : could not deduce template argument for 'std::function<TResult(void)>' from 'main::<lambda_d9d7854806072a2cb711f56185602ccb>' 
     return 100; 
    }); 

    std::function<int()> testFunc = []() { 
     return 100; 
    }; 
    int result2 = func(testFunc); // this works 

    return 0; 
} 

是否有可能推導出lambda的模板參數,以便該行編譯?而不是寫func<int>([](){ return 100; });我想寫func([](){ return 100; });

回答

4

我看不出馬上做到這一點,但你可以在與間接做到這一點:

template <typename TResult> 
TResult func(std::function<TResult()> f) { 
    return TResult(); 
} 

template <typename Fun> 
auto func(Fun f) -> decltype(f()) { 
    return func(std::function<decltype(f())>(f)); 
} 
+0

謝謝迪特馬爾!有用。 –

1

不,你不能在這裏使用std::function,編譯器不能推導出它的類型參數。

您應該只傳遞參數TFunction

2

至少如果我理解的意圖,我相信你可以做的事情是這樣的:

template <class F> 
auto foo(F &&f) -> decltype(f()) { 
    typedef decltype(f()) ret_type; 
    return ret_type(); 
} 

...或者,如果你喜歡不typedef做:

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

完全PROG RAM,對比使用情況和效果:

#include <functional> 
#include <iostream> 

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

template<typename TResult> 
TResult func(std::function<TResult()> f) { 
    return TResult(); 
} 

int main() { 
    std::cout << foo([]() { return 100; })<<"\n"; 

    std::function<int()> testFunc=[]() { return 100; }; 
    std::cout << func(testFunc) <<"\n"; // this works 

    return 0; 
} 

結果:

0 
0 
5

,我遲到了一點點:) 有一個解決方案,而std::function

template<typename Class, typename R, typename... Args> 
R resultType(R (Class::*)(Args...) const) 
{ 
    return R(); 
} 

template<typename Class, typename R, typename... Args> 
R resultType(R (Class::*)(Args...)) 
{ 
    return R(); 
} 

template<typename Functor> 
auto func(Functor f) -> decltype(resultType(&Functor::operator())) 
{ 
    return resultType(&Functor::operator()); 
} 
+0

@ThomasMcLeod我不明白你爲什麼改變我的答案。 const operator()的重載非常重要,因爲默認情況下,lambda具有const操作符()。你必須添加'可變'關鍵字,使其非常量。以下是一個示例:https://ideone.com/goHAOg 3年後編輯答案有什麼意義?甚至使它不正確? – alexeibs

+0

我完全錯過了const限定符。回滾。 – ThomasMcLeod