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

Is eliminating construction of unused object allowed in standard even if constructor has observable side-effects?

考虑以下代码:

#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;
}

使用最新的 GCC or Clang the only "Test" is printed out. But if we use an address of m object (uncomment the last line (void)&t1.m;) or transform Test class template into the regular (non-templated) class 然后调用 M 构造函数。

C++ 标准允许这种行为吗?有引述吗?

是的,标准里有写。

[temp.inst] (emphasis mine)

4 Unless a member of a class template or a member template is a declared specialization, the specialization of the member is implicitly instantiated when the specialization is referenced in a context that requires the member definition to exist or if the existence of the definition of the member affects the semantics of the program; in particular, the initialization (and any associated side effects) of a static data member does not occur unless the static data member is itself used in a way that requires the definition of the static data member to exist.

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