Luc*_*lle 97 c++ result-of decltype c++11
我在理解std::result_of
C++ 0x中的需求时遇到了一些麻烦.如果我理解正确,result_of
则用于获取调用具有某些类型参数的函数对象的结果类型.例如:
template <typename F, typename Arg>
typename std::result_of<F(Arg)>::type
invoke(F f, Arg a)
{
return f(a);
}
Run Code Online (Sandbox Code Playgroud)
我真的没有看到与以下代码的区别:
template <typename F, typename Arg>
auto invoke(F f, Arg a) -> decltype(f(a)) //uses the f parameter
{
return f(a);
}
Run Code Online (Sandbox Code Playgroud)
要么
template <typename F, typename Arg>
auto invoke(F f, Arg a) -> decltype(F()(a)); //"constructs" an F
{
return f(a);
}
Run Code Online (Sandbox Code Playgroud)
我能用这两种解决方案看到的唯一问题是我们需要:
难道我就在想,唯一的区别decltype
和result_of
是而第二个不第一个需要表达?
ken*_*ytm 84
result_of
在Boost中引入,然后包含在TR1中,最后在C++ 0x中.因此result_of
具有向后兼容的优点(具有合适的库).
decltype
在C++ 0x中是一个全新的东西,不仅限于返回函数的类型,而且是一种语言特性.
无论如何,在gcc 4.5上,result_of
实现的是decltype
:
template<typename _Signature>
class result_of;
template<typename _Functor, typename... _ArgTypes>
struct result_of<_Functor(_ArgTypes...)>
{
typedef
decltype( std::declval<_Functor>()(std::declval<_ArgTypes>()...) )
type;
};
Run Code Online (Sandbox Code Playgroud)
Bar*_*rry 11
如果你需要的东西类型不是函数调用,那就std::result_of
不适用.decltype()
可以给你任何表达式的类型.
如果我们仅限于确定函数调用的返回类型的不同方式(在std::result_of_t<F(Args...)>
和之间decltype(std::declval<F>()(std::declval<Args>()...)
),则存在差异.
std::result_of<F(Args...)
定义为:
如果表达式
INVOKE (declval<Fn>(), declval<ArgTypes>()...)
在作为未评估的操作数处理时形成良好(第5条),则成员typedef类型应为该类型命名,decltype(INVOKE (declval<Fn>(), declval<ArgTypes>()...));
否则不应有成员类型.
result_of<F(Args..)>::type
和之间的区别就在decltype(std::declval<F>()(std::declval<Args>()...)
于此INVOKE
.使用declval
/ decltype
直接,除了输入的时间要长得多之外,只有在F
可直接调用(函数对象类型或函数或函数指针)时才有效.result_of
另外还支持指向成员函数的指针和指向成员数据的指针.
最初,使用declval
/ decltype
保证SFINAE友好的表达式,但std::result_of
可能会给你一个硬错误而不是扣除失败.这已在C++ 14中得到纠正:std::result_of
现在需要SFINAE友好(感谢本文).
因此,在符合标准的C++ 14编译器上,std::result_of_t<F(Args...)>
是非常优越的.它更清晰,更短,更正确†支持更多F
s ‡.
std::result_of_t
在您可能希望它失败的情况下会成功.
‡有例外.虽然它支持指向成员的指针,result_of
但如果您尝试实例化无效的type-id,则无效.这些将包括一个返回函数或按值抽取类型的函数.例:
template <class F, class R = result_of_t<F()>>
R call(F& f) { return f(); }
int answer() { return 42; }
call(answer); // nope
Run Code Online (Sandbox Code Playgroud)
正确的用法是result_of_t<F&()>
,但这是一个你不必记住的细节decltype
.
归档时间: |
|
查看次数: |
17667 次 |
最近记录: |