为什么可以将左值传递给“std::async”,即使它采用右值引用?
Why is it possible to pass an lvalue to `std::async` even though it takes an rvalue reference?
函数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)
)有效,但我不明白为什么。
我的理解是您可以将右值绑定到 const 左值引用 - 但反之则不行。您不能将左值绑定到右值引用(不使用 std::move
将其转换为右值)。
但是 - 在调用 std::async(myfunction)
时,std::async
模板被实例化为 Function = <some_func_type>
,因此变为 std::async<some_func_type>(some_func_type&&)
。也就是说 - 它需要一个右值引用。然而,我们给它传递了一个左值。
为什么有效?
As we can see, it takes both arguments as rvalue-references, or more precisely, as "universal references" (rvalue references to the template argument types).
术语“通用引用”(或“转发引用”)不是 更精确 右值引用的术语。这是另一回事。
当您将 &&
放在这样的模板参数类型上时,它就是转发引用。根据设计,这些将绑定到左值。
tl;dr:不是右值引用。
(好吧,有点像,但是 deduction and reference-collapsing rules make it effectively not one,所以我们不称它为一个。因此这种情况的特殊名称:“转发参考".)
函数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)
)有效,但我不明白为什么。
我的理解是您可以将右值绑定到 const 左值引用 - 但反之则不行。您不能将左值绑定到右值引用(不使用 std::move
将其转换为右值)。
但是 - 在调用 std::async(myfunction)
时,std::async
模板被实例化为 Function = <some_func_type>
,因此变为 std::async<some_func_type>(some_func_type&&)
。也就是说 - 它需要一个右值引用。然而,我们给它传递了一个左值。
为什么有效?
As we can see, it takes both arguments as rvalue-references, or more precisely, as "universal references" (rvalue references to the template argument types).
术语“通用引用”(或“转发引用”)不是 更精确 右值引用的术语。这是另一回事。
当您将 &&
放在这样的模板参数类型上时,它就是转发引用。根据设计,这些将绑定到左值。
tl;dr:不是右值引用。
(好吧,有点像,但是 deduction and reference-collapsing rules make it effectively not one,所以我们不称它为一个。因此这种情况的特殊名称:“转发参考".)