【问题标题】:If a variable is assigned an object returned by a function, is it copied or created in-place?如果一个变量被分配了一个函数返回的对象,它是复制还是就地创建?
【发布时间】:2021-05-31 00:22:56
【问题描述】:

我的 CPP 文件中有类似的东西来初始化任何类之外的对象。我已经对其进行了简化,但关键是正在进行一些复杂的初始化,但我想要创建一个实例:

static MyBigObject o = []()
{
  MyBigObject ret;
  ret.Init();
  return ret; 
}();

我的问题是,这个对象是从ret 复制到o 还是由于编译器的聪明才智就地创建? “就地创建”可能有一个恰当的术语 - 安置?

如果相关的话,我正在使用 C++17(即答案取决于语言版本)。是否有明确的答案,或者这可能是特定于编译器的优化?

【问题讨论】:

  • 简而言之:几乎可以肯定是优化的。长篇:stackoverflow.com/questions/12953127/…
  • FWIW,从C++11开始,如果没有省略操作,那么如果有移动构造函数,返回的值会被移动。
  • 由于编译器的聪明才智就地创建? -- 如果编译器足够聪明,它就会这样做。为什么会浪费机会?此外,早在 1998 年标准化之前,C++ 编译器就采取了各种技巧来优化和超越竞争的 C++ 编译器。
  • 这取决于MyBigObject 支持的操作(移动构造函数等)。但是,在这种情况下,可以通过让MyBigObject 的默认构造函数完成所有需要的“复杂初始化”,而不是等待构造函数完成后调用成员函数Init(),从而消除问题。那么实例的定义可以简单的为MyBigObject o;

标签: c++ visual-studio c++17 return-value-optimization nrvo


【解决方案1】:

在这种情况下:这取决于您的编译器。这是named return value optimization,可以选择省略。即使对象在其复制/移动构造函数(及其析构函数)中具有可观察到的副作用,C++17 也允许但不要求忽略复制。

【讨论】:

  • 有一个词我从来没有新的存在过!
猜你喜欢
  • 2016-04-05
  • 1970-01-01
  • 2020-12-04
  • 2012-09-15
  • 2014-09-13
  • 1970-01-01
  • 1970-01-01
  • 2020-03-19
  • 1970-01-01
相关资源
最近更新 更多