C++11 result_of deducing my function type failed

て烟熏妆下的殇ゞ 提交于 2020-01-16 04:54:26

问题


I was trying a program below:

#include<type_traits>
using namespace std;
template <class F, class R = typename result_of<F()>::type>
R call(F& f) { return f(); }
int answer() { return 42; }

int main()
{
    call(answer); 
    return 0;
}

"call(answer)" fails to compile

VC says 'R call(F&)' could not deduce template argument for 'R'

GCC says |note: template argument deduction/substitution failed:|error: function returning a function

I'm not sure if a "function name" could be used for templates. Where did I get wrong, how to make my call(answer) work?


回答1:


You can use forwarding references in these cases:

#include<type_traits>
#include<utility>
#include<cassert>

using namespace std;

template <class F, class R = typename result_of<F()>::type>
R call(F&& f) { return std::forward<F>(f)(); }

int answer() { return 42; }

int main()
{
    assert(call(answer) == 42);
    return 0;
}

It usually avoids troubles.

That said, why your code doesn't work is nicely explained by @T.C. in his answer.
See also the comments to this question for further details.




回答2:


You are calling f as an lvalue, so:

template <class F, class R = typename result_of<F&()>::type>
//                                               ^
R call(F& f) { return f(); }



回答3:


I suppose you could avoid the second template argument and use a combination of auto and decltype().

Something like

#include<type_traits>

using namespace std;

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

int answer()
 { return 42; }

int main()
{
    call(answer); 

    return 0;
}

If you (when you) can use C++14, you can use simply auto

template <class F>
auto call(F& f)
 { return f(); } 

p.s.: sorry for my bad English.



来源:https://stackoverflow.com/questions/38088944/c11-result-of-deducing-my-function-type-failed

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!