在 C++ 中复制 return 上的构造函数

Copy constructor on return in C++

我正在尝试了解以下内容

#include <iostream>

class Number {
  int _value;
public:
  Number(int number) : _value(number) { std::cout<<"constructed!\n"; }
  Number(const Number& other) : _value(other._value) { std::cout<<"copied!\n"; }
  ~Number() { std::cout<<"destructed!\n"; }
};

Number create_number(int value) {
  Number out(value);
  return out;
}

int main() {
  Number my_number = create_number(10);
}

输出为

constructed!
destructed!

我原以为在 create_number 内部会构造一个对象,将其复制到函数的输出,然后在函数返回后销毁。

类似的事情似乎会发生,因为如果我将复制构造函数显式化

explicit Number(const Number& other) : _value(other._value) { std::cout<<"copied!\n"; }

编译器在 return out 上用 no matching constructor for initialization of 'Number' 大喊大叫。如果我在 create_number 中显式调用复制构造函数,甚至将 Number out 转换为 Number(嗯?)

return Number(out);
return (Number)out;

编译器很满意,我得到了预期的输出

constructed!
copied!
destructed!
destructed!

我觉得我遗漏了一些关于 return、复制构造函数 and/or(隐式)转换的东西。有人可以解释一下吗?

那是 copy elision。在不深入了解 C++ 标准的晦涩语言的情况下,在大多数情况下,编译器 可能 省略(优化掉)副本,但这不是必需的。这与任何其他优化一样对待。

有趣的是,这是 as-if rule 的罕见例外,其中可以观察到优化的副作用 - 请参阅这些链接中的注释。