要声明哪种类型以避免复制并确保移动返回的值

时间:2013-08-26 13:59:00

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

假设

  • 我有一个功能A f();
  • 我想将局部变量a初始化为f的返回值;
  • 我不想依赖RVO;

时,避免复制f的返回值的最佳选择(以及原因)是什么?
  1. a可能需要修改
  2. 我知道a不会被修改
  3. 选项:

    a)A a = f();  b)A&& a = f();  c)const A& = f();  d)const A&& = f();


    编辑:

    我会说:

    1. b)
    2. c)中
    3. 因为它们都使用引用并避免额外的副本(RVO也可以避免这种情况,但不能保证)。那么为什么我大部分时间都会看到选项a)?

      我想问题的核心是:我得到了a)很可能与c)具有相同的效果,那么为什么不使用c)代替a),使事情在编译器上显而易见并且独立?

2 个答案:

答案 0 :(得分:2)

如果class A有移动构造函数,那么只需使用A a = f(); 如果您对class A一无所知,则只能依靠RVO或NRVO优化。

答案 1 :(得分:2)

  

那么为什么我大部分时间都会看到选项a)?

因为所有4个选项都以完全相同的方式返回值。唯一改变的是将变量绑定到返回的临时变量的方式。

  • a)声明a类型的变量A并从临时值初始化它。这不是一个赋值,这是初始化。移动构造函数将被任何流行的编译器删除,前提是您没有明确禁止它,这意味着程序将只确保为返回值保留的存储是a变量的存储
  • c)声明变量a,它是临时的const引用,延长了临时的生命周期。这意味着临时返回值获得存储,变量a将引用它。静态地知道引用指向返回值的编译器将有效地生成与a)相同的代码。
  • b)和d),我不确定他们有什么好处。 (即使有效)我也不会在此时采用右值引用。如果我需要一个,我稍后会明确地std::move该变量。

现在:

  

a可能需要修改

如果可以修改a,请使用:

auto a = f();
  

我知道a不会被修改

如果您知道不会修改a,请使用:

const auto a = f();

使用auto可以防止任何类型不匹配。 (因此,如果A发生的话,任何隐式转换为f都不会返回类型A。哦,那些维护者......)