const值和RVO

use*_*108 2 c++ c++11

说我有这个功能:

template <class A>
inline A f()
{
  A const r(/* a very complex and expensive construction */);

  return r;
}
Run Code Online (Sandbox Code Playgroud)

声明是不是一个好主意r const,因为const变量无法移动?请注意,返回的值不是const.我正在努力解决的问题是,r确实如此const,但这样做可能不是一个好主意.然而,限定符应该是帮助编译器生成更好的代码.

Yak*_*ont 6

如此处所示,NRVO省略r了该线所隐含的副本return r;

#include <iostream>

struct A {
  const char* name;
  A( const char* name_ ):name(name_) { std::cout << "created " << name << "\n"; }
  A(A const&){ std::cout << "copied " << name << "\n"; }
  A(A &&){ std::cout << "moved " << name << "\n"; }
};

A f() {
  std::cout << "start of f()\n";
  A const r("bob");
  std::cout << "body of f()\n";
  return r;
}

int main() {
  A x = f();
}
Run Code Online (Sandbox Code Playgroud)

副本main也被删除了.

如果以其他方式阻止NRVO和RVO,则const可能导致复制对象而不是moved.如果我们A以下位置删除复制构造函数,您可以看到这个:

#include <iostream>

struct A {
  const char* name;
  A( const char* name_ ):name(name_) { std::cout << "created " << name << "\n"; }
  //A(A const&){ std::cout << "copied " << name << "\n"; }
  A(A &&){ std::cout << "moved " << name << "\n"; }
};

A f() {
  std::cout << "start of f()\n";
  A const r("bob");
  std::cout << "body of f()\n";
  return r;
}

int main() {
  A x = f();
}
Run Code Online (Sandbox Code Playgroud)

代码不再编译.虽然只要NRVO发生就不执行复制构造函数,但是const本地变量需要它的存在.

现在,NRVO需要一些东西,例如在所讨论的函数的每个执行路径上返回的单个变量:如果你"中止"并执行a return A(),NRVO被阻止,并且你的const局部变量突然强制复制到所有回归网站.

  • @user1095108 没有。如果 NRVO 发生,则没有 `const` 和非 `const` 仅通过复制或移动构造函数必须存在的要求来区分。`const` 表示必须存在复制构造函数,非 `const` 表示必须存在移动或复制构造函数。如果 NRVO 发生,则无论变量是 `const` 还是非 `const`,都不会调用 *。标准不保证 NRVO,但每个主要编译器都会这样做。 (2认同)
  • +1。我知道我不应该仅仅为了+1而评论+1。但这+1来自C ++ 11中的移动语义的主要作者。我认为可能值得一提。:-) (2认同)