即使构造函数具有可观察到的副作用,标准中是否允许消除未使用对象的构造?

αλε*_*λυτ 4 c++ language-lawyer elision

考虑以下代码:

#include <iostream>

struct M {
    M() { std::cout << "M\n"; }
};

template <class T>
struct Test {
    Test() { std::cout << "Test\n"; }
    inline static auto m = M{};
};
int main() {
    Test<int> t1;
    //Test t;
    //(void)&t1.m;
}
Run Code Online (Sandbox Code Playgroud)

使用最新的GCCClang打印出唯一的“测试”。但是,如果我们使用地址m(取消注释最后一行对象(void)&t1.m;)或转换Test类模板到常规(非模板)类M构造函数被调用。

C++ 标准允许这种行为吗?任何报价?

Sto*_*ica 5

是的,它在标准中有详细说明。

[temp.inst](强调我的)

4除非类模板的成员或成员模板是声明的特化,否则当在需要成员定义存在的上下文中引用特化时,或者如果成员定义存在,则成员的特化被隐式实例化影响程序的语义;特别是,静态数据成员的初始化(和任何相关的副作用)不会发生,除非静态数据成员本身以需要静态数据成员定义存在的方式使用

由于您的示例根本不使用静态数据成员,因此它的定义从未完全实例化。