c++ - 通用引用和本地类

标签 c++ forward forwarding perfect-forwarding forwarding-reference

在我下面的代码中,我有一个函数接受“通用引用”(F&&)。该函数还有一个内部类,它接受 F&& 的对象。在它的构造函数中。是F&&在这一点上仍然是一个普遍的引用? IE。是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&。在 Task 构造函数中没有任何变化,F&& 仍然是 L& 因此构造函数采用绑定(bind)到传递给 的左值的左值引用Async,所以你不想移动它,forward 是合适的,因为它保留了值类别,将左值作为左值转发。 (从左值移动会让 Async 的调用者感到惊讶,他们不会期望左值被静静地移动。)

当使用 R 类型的右值调用函数时,参数 F 将被推导为 R,因此 F&& R&&。在 Task 构造函数中没有任何变化,F&& 仍然是 R&& 因此构造函数采用绑定(bind)到传递给 的右值的右值引用异步,因此您可以移动它,但forward 也是合适的,因为它保留值类别,将右值作为右值转发。

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

关于c++ - 通用引用和本地类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25909134/

相关文章:

google-app-engine - 如何将所有 website.com 请求转发到 Google App Engine 上的 www.website.com?

MIPS 管道停顿 : SW after LW

c++ - DirectX Unresolved external 错误

c++ - 如果我溢出堆栈,我可以期待段错误吗

c++ - 访问前 n 个可变函数参数

model - 为什么 model.forward(input) 和 model(input) 之间有不同的输出

Python 拦截来自浏览器的 Web 流量

c++ - '+' 替换为空格 Curl C++

C++ 嵌套类前向声明​​错误

ios - 尝试使用前向类 UIViewController