【问题标题】:Returning by value to rvalue reference按值返回到右值引用
【发布时间】:2015-04-23 13:47:30
【问题描述】:

我正在研究右值引用,我对以下代码有疑问:

string func() {
    return "Paul";
}

int main()
{
    string&& nodanger = func();
    // The lifetime of the temporary is extended
    // to the life-time of the reference.
    return 0;
}

问题是:func() 返回什么?

我相信会发生这种情况:

  • func 返回一个纯右值“Paul”(由于右值->指针转换,这是一个 const char * 吗?)
  • 隐式构造了一个字符串对象(使用了哪个 ctor?)
  • 由于引用折叠规则,它被绑定到“nodanger”(这与字符串和普通引用有什么不同吗?)

【问题讨论】:

  • 这甚至不会编译。 middle_name() 是什么?你在哪里返回一个右值引用? func() 只是按值返回一个字符串,因此没有右值引用。
  • 看看这篇关于Rvalue References and Move Semantics的文章。一如既往地Alex Alllain,写了一篇超级文章。这对我帮助很大。

标签: c++ c++11 rvalue-reference


【解决方案1】:

您的func() 函数返回一个std::string prvalue。用于构造std::string 的constructor 是

basic_string( const CharT* s,
              const Allocator& alloc = Allocator() );

这个纯右值绑定到右值引用nodanger,它延长了它的生命周期以匹配引用本身的生命周期。参考折叠在这里不起作用。

这与string& 普通参考的行为有什么不同吗?

如果nodanger 是string&,则代码将无法编译,因为您无法将右值绑定到非const 左值引用。您示例中的生命周期延长行为与以下情况相同

std::string const& nodanger = func();

【讨论】:

    【解决方案2】:

    这里肯定有很多混乱。我假设middle_name() 应该是func()。

    问题是:func() 返回什么?

    它返回一个string(我假设它是一个std::string)。此返回对象使用表达式"Paul" 初始化,其类型为“array of 5 constchar”。使用的构造函数如下:

    basic_string( const CharT* s,
                  const Allocator& alloc = Allocator() );
    

    要调用此函数,字符串文字必须经过隐式数组到指针的转换(将我们从 const char[5] 带到 const char*。

    表达式func() 是纯右值表达式(右值表达式的子集),因为它按值返回。以下是标准对此的定义:

    如果结果类型是左值引用类型或对函数类型的右值引用,则函数调用是左值;如果结果类型是对对象类型的右值引用,则为 xvalue,否则为纯右值。

    说“返回纯右值”是没有意义的。 “prvalue”不是对象或类型。这是一种表达方式。调用func的表达式是prvalue。

    右值引用绑定到函数返回的std::string 对象。这里没有参考崩溃。如果引用是左值引用,您的代码将无法编译,因为非const 左值引用无法绑定到右值表达式。

    【讨论】:

      猜你喜欢
      • 2018-12-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多