【问题标题】:Storing return value as a const reference versus as a value将返回值存储为 const 引用与值
【发布时间】:2015-11-03 06:11:43
【问题描述】:

假设一个函数有签名

std::string GetString();

并且它按值返回一个新字符串。现在给出以下代码:

// (a) Store the return value to a const reference.
const std::string& my_string = GetString();

// (b) Store the return value to a (const) value.
const std::string my_string = GetString();

从 C++11 编译器的角度来看,我是否正确理解 (a) 和 (b) 是相同的?如果有,在风格的选择上是否有一个大致的共识?

【问题讨论】:

  • 如果它们相同,我会感到惊讶。在情况 b 中,您实际上有一个 std::string。在情况 a 中,您有对字符串的引用,但没有实际的 std::string 存储。它应该会崩溃,甚至可能无法编译。
  • @ChrisBecke This Q&A 解释案例 (a)。

标签: c++ const-reference


【解决方案1】:

从 C++11 编译器的角度来看,我是否正确理解 (a) 和 (b) 是相同的?

不,它们不相同。

(a) 延长GetString() 返回的临时对象的寿命。

(b) 创建一个新对象。它是由:

  1. GetString()的返回值作为参数调用std::string的复制构造函数,
  2. 被 RTO 分配返回值GetString(),或者
  3. 使用GetString()的返回值调用移动构造函数。

【讨论】:

  • 一对尼特:(a)不会“延长临时工的寿命”。 GetString 的返回值创建的临时对象已经消失,并且 (a) 是对不再存在的临时对象的引用。 (b) 由于返回值优化(因为永远)或由于移动语义(C++11 或更高版本),其中GetString() 构造的值被直接移动到声明的存储中,可能会或可能不会调用复制构造函数(b) 不调用复制构造函数。
  • @legalize,同意你的(b),而不是(a)。见Does a const reference prolong the life of a temporary?
  • @R Sahu 好的,我明白你关于 (a) 的观点。然而,这感觉像是一种边缘条件,比避免它更难记住。返回值优化/移动语义出现得更频繁,对理解 IMO 更有用。
  • @legalize,当您需要简单地查询返回的对象以获取有用信息时,它是该语言的一项功能。类型 - const& - 应该清楚地提醒对象的用途。
  • @legalize 引用绑定在 C++ 中非常常见,必须理解。实际上,如果所有引用(即右值引用)受法律约束,它们都会延长临时对象的生命周期
【解决方案2】:

理论上它们是不同的,但实际上它们是相同的。您可以编写来区分差异的唯一代码将涉及decltype(my_string)

编译器可以为两者生成相同的程序集。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-15
    • 2011-05-24
    • 1970-01-01
    相关资源
    最近更新 更多