Sta*_*ked 3 c++ forwarding forward perfect-forwarding forwarding-reference
在我的下面的代码中,我有一个接受"通用引用"(F&&)的函数.该函数还有一个内部类,它接受F&&构造函数中的对象.是F&&仍然在这一点上通用的参考?即F仍然被认为是推断类型?
换句话说,我应该使用std::forward<F>或std::move在构造函数初始化列表中?
#include "tbb/task.h"
#include <iostream>
#include <future>
template<class F>
auto Async(F&& f) -> std::future<decltype(f())>
{
typedef decltype(f()) result_type;
struct Task : tbb::task
{
Task(F&& f) : f_(std::forward<F>(f)) {} // is forward correct here?
virtual tbb::task* execute()
{
f_();
return nullptr;
}
std::packaged_task<result_type()> f_;
};
auto task = new (tbb::task::allocate_root()) Task(std::forward<F>(f));
tbb::task::enqueue(*task);
return task->f_.get_future();
}
int main()
{
Async([]{ std::cout << "Hi" << std::endl; }).get();
}
Run Code Online (Sandbox Code Playgroud)
是
F&&仍然在这一点上通用的参考?即F仍然被认为是推断类型?
这种混乱是为什么我不喜欢通用引用一词...... 没有这样的事情.
我更喜欢用左值引用和右值引用来理解代码,以及参考规则折叠和模板参数推导的规则.
当使用左值类型调用函数时L,参数F将被推导为L&,并且参考折叠规则F&&就是L&.在Task构造函数中没有任何更改,F&&仍然L&是构造函数采用绑定到传递给的左值的左值引用,Async因此您不想移动它,并且forward是合适的,因为它保留了值类别,将左值转发为左值.(从左值移动会让调用者感到惊讶Async,他们不会期望左值可以无声地移动.)
当调用该函数时用类型的一个rvalue R参数F将被推导出R,因此F&&是R&&.在Task构造函数中没有任何改变,F&&仍然R&&是构造函数采用绑定到传递给它的rvalue的rvalue引用,Async因此你可以移动它,但forward也是合适的,因为它保留了值类别,将rvalue转发为rvalue.
在上周的CppCon上,Herb Sutter宣布"通用参考"的首选术语现在转发参考,因为它更好地描述了它们的用途.
| 归档时间: |
|
| 查看次数: |
195 次 |
| 最近记录: |