为什么可以将左值传递给"std::async",即使它引用了右值

Why is it possible to pass an lvalue to `std::async` even though it takes an rvalue reference?

本文关键字:quot 引用 async 值传 std 为什么      更新时间:2023-10-16
函数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 );

正如我们所看到的,它将两个自变量都作为右值引用,或者更准确地说,作为";通用参考文献";(对模板参数类型的右值引用(。

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

我的理解是,可以将右值绑定到常量左值引用,但不能反之亦然。不能将左值绑定到右值引用(如果不使用std::move将其强制转换为右值(。

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

为什么它有效?

正如我们所看到的,它将两个参数都作为右值引用,或者更准确地说,作为"通用参考文献";(对模板参数类型的右值引用(。

术语";通用参考号";(或"转发引用"(不是右值引用的更精确的术语。这是另一回事。

当您将&&放在这样的模板参数类型上时,它就是一个转发引用。通过设计,这些将绑定到lvalues。

tl;dr:这不是右值引用

(好吧,这有点像,但推导和引用折叠规则使它有效地不是一个,所以我们不称它为一个。因此这种情况的特殊名称:"转发引用"。(