c – 通用参考和本地课程
在我的下面的代码中,我有一个接受“通用参考”(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(); } Live demo. 解决方法
这种混淆是我不喜欢通用引用这个词的原因…… there’s no such thing. 我更喜欢用左值引用和右值引用来理解代码,以及参考规则折叠和模板参数推导的规则. 当使用类型L的左值调用函数时,参数F将被推导为L&和参考折叠规则F&&只是L& ;.在任务构造函数中没有任何变化,F&&仍然是L&所以构造函数接受一个左值引用,该引用绑定到传递给Async的左值,因此你不想移动它,并且转发是合适的,因为它保留了值类别,将左值转发为左值. (从左值移动会让Async的调用者感到惊讶,他们不会期望左值可以无声地移动.) 当使用类型R的右值调用函数时,参数F将推导为R,因此F&&是R&&.在任务构造函数中没有任何变化,F&&仍然是R&&所以构造函数接受一个绑定到传递给Async的rvalue的rvalue引用,因此你可以移动它,但forward也是合适的,因为它保留了value类别,将rvalue转发为rvalue. 在上周的CppCon上,Herb Sutter宣布“通用参考”的首选术语现在转发参考,因为它更好地描述了它们的用途. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |