【问题标题】:const T& vs. T&&const T& 与 T&&
【发布时间】:2013-02-10 01:01:44
【问题描述】:

我有以下功能:

T foo();

而且,在另一个函数中,我正在使用返回的 T 值,例如:

const T& t = foo();

T&& t = foo();

我想问:

  1. 两者是等价的吗?

  2. 在内存方面,这两种方法有什么区别?

  3. 我知道在第一种方法中,临时值生命周期与参考生命周期相匹配。使用右值引用时也会出现同样的情况?

  4. 我是否应该考虑使用 const 右值引用 (const T&&)?

我正在使用第一种方法,这是我习惯的方法,并且很好地照顾我。我仍在思考右值引用和 C++11 产品。

【问题讨论】:

  • 仅仅因为你可以创建一个本地右值引用变量并不意味着它是有用的。它们主要用于参数,偶尔也会返回值。
  • T 是不是推导类型?这有很大的不同。
  • @sftrabbit:好点。我认为这个问题的意图是 T&& 实际上是一个 r 值引用,不受引用折叠规则的约束。
  • @sftrabbit:我认为它不一定是 deduced 类型。只要它是 dependent 类型,就会导致问题:ideone.com/49b9HZ
  • 当函数结果可以是结果变量静态类型的子类时,使用引用。这样你就可以避免切片,通过一些特殊的语言支持。但是,我知道的唯一用例是原始的 c++03 范围保护实现,因此很可能没有理由在您的情况下使用引用。

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


【解决方案1】:
  1. 不,它们有不同的类型。

  2. 实现定义,但不太可能有任何区别。

  3. 生命周期延长对右值和左值引用的作用相同。但是规则比“临时值生命周期匹配引用生命周期”要复杂。

  4. 可能不会。我当然不会去寻找使用它的地方。如果你有它的用处,最好是这样一个显着的改进,以证明使用这种不寻常的组合以及将来人们阅读它时会产生的混乱是合理的。

【讨论】:

    【解决方案2】:
    1. 它们基本相同(适用于临时工的终身延长),但一个是const,一个不是。
    2. “内存方面”可能没有任何区别,但这取决于实现。
    3. 是的。
    4. 我无法想象你会想要这样的情况。

    但是,移动语义确实使您使用的技术过时了。它最初是为了让人们避免制作不必要的副本,但现在有了移动语义,以前昂贵的东西现在实际上是免费的,而且可读性更高。

    【讨论】:

    • Re:'移动语义使这个过时':如果T 有一个正确的移动赋值运算符,你可以简单地写T t = foo(); 而没有任何不必要的副本,对吧?
    • @us2012 否,T t = foo() 中的赋值运算符不相关。这将是移动构造函数。但是,编译器可能会忽略这一点,因此甚至不会发生移动。
    【解决方案3】:

    如果您想知道何时以及是否使用 &&,我强烈建议您观看

    http://channel9.msdn.com/Shows/Going+Deep/Cpp-and-Beyond-2012-Scott-Meyers-Universal-References-in-Cpp11

    恕我直言,这绝对值得投入时间。

    据我了解:

    1+2) 取决于T的类型

    3) 对引用值的生命周期没有影响。旁注:无论 T&& 最终是类型明智的,它现在都有一个名称:t,因此是一个 l 值。

    4) 有点针对我自己:你是如何摆脱 const 的?

    最好的乔辰

    编辑:添加空行。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-12-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多