std::result_of<T>
要求T
是一种类型 - 但不只是任何类型。 T
必须是一个函数式所以result_of
这部分特将被使用:
template <class Fn, class... ArgTypes> struct result_of<Fn(ArgTypes...)>;
使得:
decltype(INVOKE(declval<Fn>(), declval<ArgTypes>()...))
是公形成(C++ 11 20.9.7.6) 。 (INVOKE在20.8.2中定义)
原因std::result_of<f(int)>
不起作用是因为f
不是类型 - 它是函数类型的一个实例。要声明x
是应用于int
的f
返回类型,简单地写:
decltype(f(int{})) x;
或者如果你喜欢硬编码的int
:
decltype(f(32)) x;
如果类型f
然后用:
using FuncPtr = decltype(f);
在所提供的代码F
(即,不小写f
)然而是一种类型的,因此F(int)
限定了代表返回F
受理int
为参数的函数的类型。显然这不是F的意思! F
的类型是一个结构,它的实例可以使用函数调用操作符。 F
也没有明确或隐含的构造函数,也可以使用int
等。这如何工作?简短的回答:模板“魔术”。
本质上,std::result_of
的定义采用类型F(int)
并将返回类型与参数类型分开,以便确定哪种情况的INVOKE()可以使其工作。 INVOKE的情况是:
- F是一个指针,指向用于一些T级
- 一个成员函数如果只有一个参数,F是一个指针,指向类T的数据成员,或者,
- 一架F的实例可以作为一个功能,即,
declval<F>()(declval<int>())
它可以是一个普通的函数调用或某些类型的函子(例如,像您的例子)。
一旦确定result_of
可以确定有效表达式的返回类型。这是通过result_of
的type
成员返回的内容。
关于这件事的美妙之处在于,result_of
的用户不需要知道任何有关这个实际工作方式的信息。唯一需要了解的是result_of
需要一个函数TYPE。如果使用的是代码中不是类型的名称(例如,f
),则需要使用decltype
来获取具有这种类型的表达式的类型。
最后,为什么f
不能被视为一个类型的部分原因是模板参数也允许常量值,而f
是一个常量函数指针值。这是很容易证明(使用f
问题的定义):
template <double Op(int)>
double invoke_op(int i)
{
return Op(i);
}
及更高版本:
std::cout << invoke_op<f>(10) << std::endl;
因此,要获得正确调用f
一些int
表达式的返回值的类型一会写:
decltype(f(int{}))
(注:f
不会被调用:编译器简单地使用内decltype
表达以确定其结果即在这种情况下它的返回值。)
的解决方案是使用本'的std ::的result_of :: type x;'。如果您想深入了解,请查看http://stackoverflow.com/q/2763824/893693 –
inf
2012-07-13 13:22:51