【问题标题】:Why is it possible to pass an lvalue to `std::async` even though it takes an rvalue reference? [duplicate]为什么即使它需要一个右值引用,也可以将左值传递给`std::async`? [复制]
【发布时间】:2020-07-08 15:46:20
【问题描述】:

函数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 = &lt;some_func_type&gt;,因此变为 std::async&lt;some_func_type&gt;(some_func_type&amp;&amp;)。也就是说 - 它需要一个右值引用。但是,我们将它传递给一个左值。

为什么会起作用?

【问题讨论】:

  • 通用引用不是右值引用,它们就是这样得名的
  • 官方名称是转发参考btw
  • @idclev463035818 确实,但如果我理解正确的话,通用参考Function&amp;&amp; 因为Thing&amp;&amp;Function = Thing。对吗?
  • 请注意,当T = int &amp;,然后T &amp;&amp; = int &amp;(不是int &amp;&amp;)以来,粗略地说,引用到引用被简化为只是引用,结果是一个右值引用,仅在“右值引用到右值引用”的情况,在所有其他三种情况下都是左值引用。非正式地,折叠规则是&amp; = &amp; &amp; = &amp;&amp; &amp; = &amp; &amp;&amp;&amp;&amp; &amp;&amp; = &amp;&amp;。因此T &amp;&amp; 形式的类型可以是任何类型的引用、右值或左值,而不仅仅是右值。

标签: c++ rvalue lvalue


【解决方案1】:

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

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

当您将&amp;&amp; 放在这样的模板参数类型上时,它是一个转发引用。这些将根据设计绑定到左值。

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

(好吧,有点像,但是deduction and reference-collapsing rules make it effectively not one,所以我们不称它为一个。因此这种情况的特殊名称:“转发引用”。)

【讨论】:

    猜你喜欢
    • 2020-01-23
    • 1970-01-01
    • 1970-01-01
    • 2021-11-01
    • 1970-01-01
    • 2017-05-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多