微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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宣布“通用参考”的首选术语现在转发参考,因为它更好地描述了它们的用途.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐