C++ 通用参考和本地类
在下面的代码中,我有一个函数,它接受“通用引用”(C++ 通用参考和本地类,c++,forward,forwarding,perfect-forwarding,forwarding-reference,C++,Forward,Forwarding,Perfect Forwarding,Forwarding Reference,在下面的代码中,我有一个函数,它接受“通用引用”(F&&)。函数还有一个内部类,它在构造函数中接受F&的对象。在这一点上,F&仍然是一个通用的参考吗?也就是说,F是否仍被视为推断类型 换句话说,我应该在构造函数初始化列表中使用std::forward还是std::move #include "tbb/task.h" #include <iostream> #include <future> template<class F> auto Async(F&
F&&
)。函数还有一个内部类,它在构造函数中接受F&
的对象。在这一点上,F&
仍然是一个通用的参考吗?也就是说,F
是否仍被视为推断类型
换句话说,我应该在构造函数初始化列表中使用std::forward
还是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();
}
#包括“tbb/task.h”
#包括
#包括
模板
自动异步(F&&F)->std::future
{
typedef decltype(f())结果类型;
结构任务:tbb::任务
{
Task(F&&F):F_(std::forward(F)){}//这里的forward正确吗?
虚拟tbb::任务*执行()
{
f_u2;();
返回空ptr;
}
std::打包任务f;
};
自动任务=新建(tbb::task::allocate_root())任务(std::forward(f));
tbb::任务::排队(*任务);
返回任务->f_.get_future();
}
int main()
{
异步([]{std::coutctor不是一个通用引用,而是一个bog标准右值引用或左值引用。构造的问题是您不知道是哪个,只是它镜像了异步(这可能足够了)
为了成为一个通用引用,必须为该调用推导类型,而不是更早地为某个相关调用推导类型
std::forward
i仍然适用于此,因为outer functions参数确实应该传递给具有保留的move-/copy语义的已创建对象
此时,F&&
是否仍然是一个通用的参考?即,F
是否仍然被认为是一个推断类型
这种混乱正是我不喜欢“普遍参照”这个词的原因
我更喜欢从左值引用和右值引用的角度来理解代码,以及引用折叠和模板参数推断的规则
当使用类型为L
的左值调用函数时,参数F
将被推断为L&
,通过引用,折叠规则F&&
只是L&
。在任务
构造函数中,没有任何变化,F&
仍然是L&
,因此构造函数采用左值引用绑定到传递给Async
的左值的ence,因此您不想移动它,forward
是合适的,因为它保留了值类别,将左值作为左值转发。(从左值移动会让Async
的调用方感到惊讶,因为他们不希望左值被静默地移动。)
当使用类型为R
的右值调用函数时,参数F
将被推断为R
,因此F&&
是R&
。在任务
构造函数中,没有任何变化,F&
仍然是R&
,因此构造函数采用绑定到右值pa的右值引用sed为Async
,因此可以将其移动,但forward
也很合适,因为这样会保留值类别,将右值作为右值转发
上周在CppCon上,赫伯·萨特宣布“通用参考”的首选术语现在是转发参考,因为这更好地描述了它们的用途。酷孩子们称它们现在不是通用参考。(Cos)感谢您的解释。认识到std::forward仅仅意味着保留值类别带来了很多清晰。