0

假设

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

什么是避免f被复制的返回值的最佳选择(以及为什么)

  1. a可能需要修改
  2. 我知道a不会修改

选项:

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


编辑:

我会说:

  1. b)
  2. C)

因为两者都使用引用并避免了额外的副本(RVO 也可以避免,但不能保证)。那么我怎么会看到选项a)大部分时间都建议?

我想问题的核心是:我知道 a) 很可能与 c) 具有相同的效果,那么为什么不使用 c) 而不是 a),以使事情明确且独立于编译器?

4

2 回答 2

2

如果class A有 move-constructor 则只需使用A a = f(); 如果您对您一无所知,class A则只能依靠 RVO 或 NRVO 优化。

于 2013-08-26T14:15:36.747 回答
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(因此,对if的任何隐式转换毕竟f不会返回类型。哦,那些维护者......)A

于 2013-08-27T05:13:21.543 回答