Code Bye

为什么本人的这个result_of编译不过

#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() (函数)
参数为 F&& 时,F被推导为 int(&)() (函数引用:

这个是result_of的规则吗,还是universal reference的推导规则?
谢谢。

后者

4

引用:

”而 result_of 的模板参数 F() 表示一个函数类型,F 是函数的返回值。“这句话有点起义。
result_of<Fun(Arg….)>这里F就是一个函数对吧,原因是本人可以

int F(){return 1;}
result_of<F()>::type //得到返回值类型

为什么说F()表示一个函数类型而F是函数的返回值呢? 在上面两行代码中,F并不是返回值啊?

你写的那两行代码过不了编译。F 实际是什么并不重要,但编译器会把 F() 的形式认为是一个函数类型,并将这个类型传递给模板 result_of 的参数

4

根据语言规则, F() 作为 type-id 的时候就代表 返回 F 的函数。例如当 F 是 int的时候, F() 就等同于 int() ,也就是
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

std::result_of<F()>::type,
F 只能是:函数的引用:
Quote: 引用:

根据语言规则, F() 作为 type-id 的时候就代表 返回 F 的函数。例如当 F 是 int的时候, F() 就等同于 int() ,也就是

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&,否则对于一些特别的函数对象会推导出错误的结果

本人试了一下,下面这样是可以的:

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

引用:
Quote: 引用:

std::result_of<F()>::type,
F 只能是:函数的引用:

Quote: 引用:

按照你引用的红色字:

3 A callable type is a function object type (20.8) or a pointer to member.
4 A callable object is an object of a callable type.

函数就不是callable type,对吗?

对,函数类型并不属于这里定义的 callable type 。


CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明为什么本人的这个result_of编译不过