首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >const值与RVO

const值与RVO
EN

Stack Overflow用户
提问于 2013-08-26 02:33:54
回答 2查看 1.2K关注 0票数 4

假设我有这个功能:

代码语言:javascript
复制
template <class A>
inline A f()
{
  A const r(/* a very complex and expensive construction */);

  return r;
}

声明r const是个好主意,因为const变量不能移动?注意,返回的值不是const。我所担心的是,r确实是const,但宣布它为const可能不是一个好主意。然而,限定符应该有助于编译器生成更好的代码。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-08-26 02:45:40

作为在此演示,NRVO继承了行return r;所隐含的r的副本。

代码语言:javascript
复制
#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();
}

main中的副本也被删除。

如果以其他方式阻止NRVO和RVO (例如在与GCC一起编译时使用标志-fno-elide-constructors ),则const可以使您的对象被复制而不是moved。

代码语言:javascript
复制
#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();
}

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

现在,NRVO需要一些东西,例如沿着所述函数的每个执行路径返回的单个变量:如果您曾经“中止”并执行return A(),则NRVO将被阻塞,并且您的const局部变量突然强制在所有返回站点上复制。

票数 7
EN

Stack Overflow用户

发布于 2013-08-26 02:54:42

如果class A在您的控制下,并且希望通过移动返回const对象,则可以这样做

代码语言:javascript
复制
mutable bool resources_were_stolen = false;

并在const移动构造函数中将其设置为true。

代码语言:javascript
复制
A(const A&& other) { ...; other.resources_were_stolen = true; }
~A() { if (!resources_were_stolen) ... }

实际上,使用对象在构造和破坏过程中丢失const-ness这一事实,析构函数可能会变成const

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18435820

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档