c – 通用参考和本地课程

在我的下面的代码中,我有一个接受“通用参考”(F&&)的功能.该函数还有一个内部类,它接受F&&amp ;;的对象.在它的构造函数中.是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.

解决方法

Is F&& still a universal reference at that point? I.e. is F still considered to be a deduced type?

这种混淆是我不喜欢通用引用这个词的原因…… there’s no such thing.

我更喜欢用左值引用和右值引用来理解代码,以及参考规则折叠和模板参数推导的规则.

当使用类型L的左值调用函数时,参数F将被推导为L&和参考折叠规则F&&只是L&amp ;.在任务构造函数中没有任何变化,F&&仍然是L&所以构造函数接受一个左值引用,该引用绑定到传递给Async的左值,因此你不想移动它,并且转发是合适的,因为它保留了值类别,将左值转发为左值. (从左值移动会让Async的调用者感到惊讶,他们不会期望左值可以无声地移动.)

当使用类型R的右值调用函数时,参数F将推导为R,因此F&&是R&&.在任务构造函数中没有任何变化,F&&仍然是R&&所以构造函数接受一个绑定到传递给Async的rvalue的rvalue引用,因此你可以移动它,但forward也是合适的,因为它保留了value类别,将rvalue转发为rvalue.

在上周的CppCon上,Herb Sutter宣布“通用参考”的首选术语现在转发参考,因为它更好地描述了它们的用途.

相关文章

本程序的编译和运行环境如下(如果有运行方面的问题欢迎在评...
水了一学期的院选修,万万没想到期末考试还有比较硬核的编程...
补充一下,先前文章末尾给出的下载链接的完整代码含有部分C&...
思路如标题所说采用模N取余法,难点是这个除法过程如何实现。...
本篇博客有更新!!!更新后效果图如下: 文章末尾的完整代码...
刚开始学习模块化程序设计时,估计大家都被形参和实参搞迷糊...