为什么即使使用右值引用也可以将左值传递给`std :: async`?

时间:2020-07-08 15:46:20

标签: c++ rvalue lvalue

函数std::async的定义如下:

template< class Function, class... Args>
std::future<std::result_of_t<std::decay_t<Function>(std::decay_t<Args>...)>>
    async( Function&& f, Args&&... args );

如我们所见,它将两个参数都作为rvalue-references,或更准确地说,作为“通用引用”(对模板参数类型的rvalue引用)。

传递一个简单的函数指针(例如std::async(myfunction))是可行的,而我不明白为什么。

我的理解是,您可以将右值绑定到const左值引用-但不能相反。您不能将左值绑定到右值引用(不使用std::move将其强制转换为右值)。

但是-调用std::async(myfunction)时,std::async模板被Function = <some_func_type>实例化,因此变成std::async<some_func_type>(some_func_type&&)。也就是说-它需要一个右值引用。但是,我们为它传递了一个左值。

为什么起作用?

1 个答案:

答案 0 :(得分:1)

如我们所见,它将两个参数都作为rvalue-references,或更准确地说,作为“通用引用”(对模板参数类型的rvalue引用)。

术语“通用引用”(或“转发引用”)不是右值引用的更精确术语。这是另一回事。

&&放在这样的模板参数类型上时,它就是转发参考。这些将按设计绑定到左值。

tl; dr:它不是右值引用。

(好的,虽然是deduction and reference-collapsing rules make it effectively not one,所以我们不称其为。因此,这种情况的特殊名称:“转发参考”。)