前几天,我遇到了一些意外行为,并将其简化为以下几行代码。我在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/

10-12 16:04