为什么初始化不调用赋值运算符

Why didn't initialization call the assignment operator

查看以下代码

#include <iostream>
#include <vector>
#include <list>
using namespace std;
struct X {
  X() {  std::cout << "X() " << std::endl; }
  X(const X &) {  std::cout << "X(const X &) " << std::endl; }
  X &operator=(const X &) { std::cout << "operator= "<< std::endl; return *this;}
};

X f5() {
  X x;
  return x;
}

int main() {
  //Case 1:
  cout << "case 1:"<<'\n';
  X x5 = f5();
  //Case 2:
  cout << "case 2:"<<'\n';
  X x1;
  X x2 = x1;
  return 0;
}

输出:

case 1:
X()
case 2:
X()
X(const X &)

如果你查看输出,你会发现案例2调用了拷贝构造函数,而案例1没有。所以为什么?是什么导致了差异。在我看来,两者都在做同样的事情,即初始化。

当返回一个立即分配给另一个对象的临时对象时,允许编译器进行称为复制省略的优化:https://en.cppreference.com/w/cpp/language/copy_elision

这样就避免了额外的构造。