#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)这句话提示错误
VC提示”R call(F&)” could not deduce template argument for “R”
GCC提示|note: template argument deduction/substitution failed:|error: function returning a function
到底错在哪里? 怎么样才能让本人的call(answer)调用成功?
4
template <class F, class R = typename result_of<F()>::type> R call(F&& /*参数类型修改*/ f) { return f(); }
4
参数为 F&& 时,F被推导为 int(&)() (函数引用:
这个是result_of的规则吗,还是universal reference的推导规则?
谢谢。
后者
4
你写的那两行代码过不了编译。F 实际是什么并不重要,但编译器会把 F() 的形式认为是一个函数类型,并将这个类型传递给模板 result_of 的参数
4
int f();
中 f 的类型,也就是 返回 int 的函数
std::result_of 可以把传给它的 type-id “拆解”成几个部分,从而“还原”出 F ,然后根据 F 得出想要的类型。但是当语言规则根本不允许形成 F() 的时候,std::result_of 就没有动手的机会
另外正如 StackOverflow上有人指出的
template <class F, class R = typename result_of<F()>::type>
R call(F& f) { return f(); }
参数 f 是一个 左值(lvalue),所以传给 result_of 的不应是 F 而应是 F&,否则对于一些特别的函数对象会推导出错误的结果
4
F 只能是:函数的引用:
本人试了一下,下面这样是可以的:
struct S { double operator()(){return 0.0;} }; template <class F, class R = typename result_of<F()>::type> R call(F& f) { return f(); } int main() { S obj; call(obj); return 0; }好像和你说的想法,F&可以作用与函数对象,但是作用于函数就不行。
如下,obj() 可行,但 result_of 会炸,就是前述“错误的结果”。把 result_of<F()> 换成 result_of<F&()> 就不会出这个问题。这算是题外话
struct S { double operator()() & {return 0.0;} }; template <class F, class R = typename result_of<F()>::type> R call(F& f) { return f(); } int main() { S obj; call(obj); return 0; }
4