我看到它std::async的具体说明如下:
template <class F, class... Args> // copied out of the standard
future<typename result_of<F(Args...)>::type>
async(F&& f, Args&&... args);
Run Code Online (Sandbox Code Playgroud)
我曾预料到它会被声明为:
template <class F, class... Args>
auto async(F&& f, Args&&... args) ->
future<decltype(forward<F>(f)(forward<Args>(args)...)>;
Run Code Online (Sandbox Code Playgroud)
那是相同的,还是有某种方式使用它比使用result_of更好decltype?(我理解它result_of适用于类型,同时decltype适用于表达式.)
Luc*_*ton 11
您的版本不适用于例如指向成员的指针.更接近但仍然不准确的版本是:
template <class F, class... Args>
auto async(F&& f, Args&&... args)
-> future<decltype( ref(f)(forward<Args>(args)...) )>;
Run Code Online (Sandbox Code Playgroud)
剩下的唯一区别std::result_of是,它将functor转换为左值(您的版本也共享的问题).换句话说,这种呼叫(通过一个std::reference_wrapper<F>)的结果是typename std::result_of<F&(Args...)>::type.
这是一个尴尬的局面,其中标准库的几个组成部分(仅举几例,除了那些我们刚刚见证:std::thread,std::bind,std::function)在一个难以捉摸的条款规定INVOKE(F,A0,A1,..., aN)伪表达式,它不完全等同于f(a0, a1, ... aN).由于std::result_of是其中一个组件,并且实际上用于计算INVOKE的结果类型,这就是您注意到的差异.
因为没有std::invoke与std::result_of类型特征串联的结果,我认为后者仅用于描述例如相关标准库组件的返回类型,当您的代码调用它们时.如果你想要一种简洁的,自我记录的写作方式,例如返回类型(一个非常有价值的可读性目标,与洒水decltype无处不在),那么我建议你编写自己的别名:
template<typename F, typename... A>
using ResultOf = decltype( std::declval<F>()(std::declval<A>()...) );
Run Code Online (Sandbox Code Playgroud)
(如果你想要使用别名ResultOf<F(A...)>而不是ResultOf<F, A...>那么你需要一些机制来模拟匹配函数签名.)
这个别名的另一个好处是它与SFINAE友好,不像std::result_of.是的,这是它的一个缺点.(公平地说,虽然已经对即将推出的标准进行了修改,但实施方案已经适用了.)
如果你使用这样的特性,你不会错过任何东西,因为你可以通过调整成员的指针std::mem_fn.
从功能的角度来看,没有任何区别.但是,该decltype版本使用trailing-return-type,这与编程的观点有一点不同.
在C++ 11中,std::result_of并非绝对必要,可以使用decltype,就像你使用的方式一样.但是std::result_of向后兼容第三方库(较旧的),例如Boost result_of.但是,我没有看到太多的优势.
就个人而言,我更喜欢使用,decltype因为它更强大,适用于任何实体,而result_of只适用于可调用实体.所以,如果我使用decltype,我可以随处使用它.但是result_of,我偶尔会切换到decltype(也就是说,当实体不可调用时).在github上看到这个我decltype在所有函数的返回类型中使用的地方.
你的问题已经有了不同之处:"我理解它result_of适用于类型,而decltype适用于表达式."
它们都提供相同的功能(std::result_of甚至可以用decltype现在的方式实现),并且您的示例的差异大部分都不存在,因为您已经拥有构建表达式所需的变量.
也就是说,当你只有类型时,差异归结为语法糖.考虑:
typename std::result_of< F( A, B, C ) >::type
Run Code Online (Sandbox Code Playgroud)
与
decltype( std::declval<F>()( std::declval<A>(), std::declval<B>(), std::declval<C>() )
Run Code Online (Sandbox Code Playgroud)
请记住,std::result_of在这些情况下,这是一个选项.
请注意,也有一些情况decltype可以以不能使用的方式使用std::result_of.考虑一下decltype( a + b ),就我所知,你找不到F创建一个等价物std::result_of< F( A, B ) >.
| 归档时间: |
|
| 查看次数: |
1973 次 |
| 最近记录: |