在初始化列表中复制省略?

ale*_*099 5 c++ move-constructor copy-elision

考虑这个类

class A {
public:
    tracker tra;
    A(tracker _t) : tra(_t) {}
};
Run Code Online (Sandbox Code Playgroud)

并通过调用它

A a {tracker()};
Run Code Online (Sandbox Code Playgroud)

创建的对象tracker()在被存储到之前永远不会被使用a.tra

为什么编译器不优化所有的复制结构?

跟踪器定义如下:

class tracker {
public:
    void mark(const char* v) {
        std::cout << v << ' ' << this << std::endl;
    }

    tracker() {
        mark("con");
    }

    tracker(const tracker& o) {
        mark("cpy");
    }

    tracker(tracker&& o) {
        mark("mov");
    }

    ~tracker() {
        mark("des");
    }

    tracker& operator=(const tracker&) {
        mark("=cp");
        return *this;
    }

    tracker& operator=(tracker&&) {
        mark("=mv");
        return *this;
    }
};
Run Code Online (Sandbox Code Playgroud)

wha*_*ned 5

在这种情况下,编译器无法优化 的复制构造,tracker因为 的复制构造函数和析构函数tracker具有可观察到的副作用。如果编译器优化了复制构造而忽略了这一点,它将改变程序的可观察行为,从而违反as-if 规则

假设规则有一个例外,即允许编译器优化复制/移动构造,即使复制/移动构造函数和/或析构函数具有可观察到的副作用。(复制省略

但该例外规则仅适用于某些情况,而您的代码不是其中之一。tra您正在(复制)构造具有类型 的左值的成员变量tracker。这不是复制省略规则中提到的情况。