您想问的问题可能与此问题重复:为什么 std::result_of 采用(不相关的)函数类型作为类型参数? https://stackoverflow.com/questions/15486951/why-does-stdresult-of-take-an-unrelated-function-type-as-a-type-argument
我们来剖析一下:
std::result_of<F(Ts...)>::type
所以,在某个地方namespace std
,我们有一个类模板result_of<>
。它需要一个模板类型参数;也就是说,它看起来基本上是这样的:
template<typename Foo>
struct result_of
{
typedef FOOBARBAZ type;
};
好的,我们用参数实例化这个模板F(Ts...)
。这是不寻常的语法!你想必知道Ts
是一个参数包,因此Ts...
括号内的内容将在编译时扩展为逗号分隔的类型列表,例如int, double, bool
。所以我们有F(int, double, bool)
。好的,这是一个函数类型。
Just as int(char)
意思是“功能采取char
并返回int
”,也如此F(int, double, bool)
意思是“功能采取int, double, bool
并返回F
".
“但是等等,”你说。 “我想F
已经是我的功能类型了!”
Yes. F
is your函数类型。但期望的类型std::result_of
is, really!,该函数类型包含在another函数类型。详细说明:
typedef int (*F)(char);
typedef F G(char);
static_assert(std::is_same< std::result_of<G>::type, int >::value);
static_assert(std::is_same< std::result_of<F(char)>::type, int >::value);
static_assert(std::is_same< std::result_of<int (*(char))(char)>::type, int >::value);
上面的每一行都完全相同:F(char)
只是一种更美观的写作方式int (*(char))(char)
。当然,你不可能总是侥幸逃脱,因为有时F
是不能从函数返回的函数类型:
typedef int F(char);
std::result_of<F(char)>; // fails to compile
正如@Simple 在评论中写道,std::result_of<F(Ts...)>::type
总是可以用不太聪明但也不那么令人困惑的表达来代替
decltype( std::declval<F>() ( std::declval<Ts>()... ) )
即“decltype
调用类型值的结果F
带有类型参数Ts...
。在这里,没有古怪的高级函数类型;一切都按照您自然期望的方式进行。就我个人而言,我可能会使用decltype
在我自己的代码中使用这种方法,只是因为它更容易理解;但我想有些人会更喜欢std::result_of
方法,因为它表面上看起来更简单并且受到标准的支持。每个人都有自己的。 :)