假设
A f()
; a
初始化为f
的返回值; 时,避免复制
f
的返回值的最佳选择(以及原因)是什么?
a
可能需要修改a
不会被修改选项:
a)A a = f();
b)A&& a = f();
c)const A& = f();
d)const A&& = f();
编辑:
我会说:
因为它们都使用引用并避免额外的副本(RVO也可以避免这种情况,但不能保证)。那么为什么我大部分时间都会看到选项a)?
我想问题的核心是:我得到了a)很可能与c)具有相同的效果,那么为什么不使用c)代替a),使事情在编译器上显而易见并且独立?
答案 0 :(得分:2)
如果class A
有移动构造函数,那么只需使用A a = f();
如果您对class A
一无所知,则只能依靠RVO或NRVO优化。
答案 1 :(得分:2)
那么为什么我大部分时间都会看到选项a)?
因为所有4个选项都以完全相同的方式返回值。唯一改变的是将变量绑定到返回的临时变量的方式。
a
类型的变量A
并从临时值初始化它。这不是一个赋值,这是初始化。移动构造函数将被任何流行的编译器删除,前提是您没有明确禁止它,这意味着程序将只确保为返回值保留的存储是a
变量的存储a
,它是临时的const引用,延长了临时的生命周期。这意味着临时返回值获得存储,变量a
将引用它。静态地知道引用指向返回值的编译器将有效地生成与a)相同的代码。std::move
该变量。现在:
a可能需要修改
如果可以修改a
,请使用:
auto a = f();
我知道a不会被修改
如果您知道不会修改a
,请使用:
const auto a = f();
使用auto
可以防止任何类型不匹配。 (因此,如果A
发生的话,任何隐式转换为f
都不会返回类型A
。哦,那些维护者......)