前几天,我遇到了一些意外行为,并将其简化为以下几行代码。我在VC++ 19.0,Clang 3.8和GCC 5.4.0以及8.2.0上进行了测试。在每种情况下,输出仅为1
,而我曾期望它的输出在Hello
之前,并在Goodbye
之前完成。
#include <iostream>
template <class T> struct X { static T data; };
template <class T> T X<T>::data;
struct A
{
A()
{
std::cout << "Hello" << std::endl;
}
~A()
{
std::cout << "Goodbye" << std::endl;
}
};
struct B : X<A> { };
int main(int argc, char **argv)
{
std::cout << sizeof(B::data) << std::endl;
}
显然
B::data
存在,但从未调用过其构造函数和析构函数。有趣的是,如果我将此添加到测试中assert(typeid(B::data) == typeid(A));
GCC的行为符合我最初的预期,但Clang和VC++的行为均与以前相同。所以我在这里怀疑行为是不确定的,而不仅仅是意外的。我对语言标准的措辞还不熟悉,无法为自己准确说明这种情况下的违规行为。但这肯定与我对静态成员和继承如何工作的直觉相抵触。
最佳答案
根据[temp.inst]/3:
和[expr.context]/1:
X<A>::data
仅用作sizeof
的操作数,它是未评估的操作数,因此X<A>::data
未初始化。
对于typeid
,我认为这是一个GCC错误。
关于c++ - 为什么这个静态成员即使存在也没有构造?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/51800294/