即使构造函数具有可观察到的副作用,标准中是否允许消除未使用对象的构造?
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.
由于您的示例根本不使用静态数据成员,因此它的定义永远不会完全实例化。
考虑以下代码:
#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.
由于您的示例根本不使用静态数据成员,因此它的定义永远不会完全实例化。