【发布时间】:2018-08-11 13:50:58
【问题描述】:
前几天我遇到了一些意想不到的行为,并将其简化为这几行代码。我在 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++ 的行为与以前一样。所以我在这里的怀疑是行为是未定义的,而不仅仅是意外。我对语言标准措辞不够熟悉,无法准确地说出这种情况下的违规行为。但这肯定违背了我对静态成员和继承如何工作的直觉。
【问题讨论】:
-
您的第一个代码从不实例化 B 对象。
-
@NeilButterworth instantiating B object won't help。应该在某处使用
X::data。喜欢static_cast<void>(B::data);
标签: c++ templates inheritance static