了解调用哪个构造函数

Understanding which constructor gets called

本文关键字:构造函数 调用 了解      更新时间:2023-10-16

我有一个存储 int 的结构:

struct foo {
    int value;
    foo(int value) : value(value) {
        std::cout << "value constrn";
    }
    foo(foo const&) {
        std::cout << "copy constrn";
    }
    foo(foo&&) {
        std::cout << "move constrn";
    }
};

在主方法中,我执行以下操作:

foo bar = foo(foo(foo(42)));

在这一点上,我希望首先调用通常的构造函数,然后多次移动构造函数,因为参数将是一个右值。但是,输出只是"价值构建"。

为什么既不调用复制也不调用移动构造函数,在这个例子中实际发生了什么?

由于 Copy elision,将调用相应的构造函数来直接构造对象,将省略复制/移动构造函数。自 C++17 以来,这种行为是有保证的。

在以下情况下,编译器需要省略 类对象的复制和移动构造函数,即使复制/移动 构造函数和析构函数具有可观察到的副作用:

  • 在初始化中,如果初始值设定项表达式是 prvalue,并且源类型的 cv 非限定版本与 目标的类,初始值设定项表达式用于 初始化目标对象:

    T x = T(T(T())); // only one call to default constructor of T, to initialize x