【发布时间】:2020-03-21 22:44:43
【问题描述】:
最小的例子和问题
在这个例子中,一个非模板类的内联静态成员变量c2在类成员被实例化时被初始化,而模板类的成员变量c1没有被初始化。有什么区别?为什么c1 没有被初始化,除非我通过获取它的地址来强制它,并且c2 被无条件地初始化?
struct C1 {
C1() { std::cerr << "C1()\n"; }
};
struct C2 {
C2() { std::cerr << "C2()\n"; }
};
template<typename T>
struct Template {
inline static C1 c1;
};
struct Nontemplate {
inline static C2 c2;
};
int main() {
Template<int> a;
Nontemplate b;
(void)a;
(void)b;
}
// Output:
C2()
上下文和推理
以下是最小示例的一些上下文。我有从Template<something> 继承的Nontemplate 类,c2 的构造函数依赖于c1。我希望在c2 之前创建c1;然而,事实并非如此。
template<typename T>
struct Template {
inline static C1 c1;
};
struct Nontemplate : public Template<int> {
struct C2 {
C2() {
std::cerr << "Do something with Nontemplate::C1\n";
std::cerr << "&Nontemplate::c1 = " << &Nontemplate::c1 << "\n";
}
};
inline static C2 c2;
};
int main() {
Nontemplate b;
(void)b;
}
// Output:
Do something with Nontemplate::C1
&Nontemplate::c1 = 0x600ea8
C1()
代码是使用带有-std=c++17 标志的g++ 7.2 编译的。 -O0 和 -O2 都给出相同的结果。
【问题讨论】:
-
什么编译器?实现之间是否一致? (不同的静态初始化在几个 Clang / GCC / ICC 版本之间是“古怪的”,不管标准读数可能表明什么......)
-
@user2864740 g++ 7.2。我更新了问题。
-
@HolyBlackCat 那么,模板类的静态变量属于动态初始化,非模板类的静态变量属于静态初始化?这解释了一切。看来我不应该这样解决问题。您能否将其发布为答案,以便我接受?
-
@IvanSmirnov 不,静态初始化本质上是针对具有
constexpr构造函数/初始化程序的变量。否则,非模板类的静态变量被初始化为动态初始化的一部分(“有序动态初始化”)。 “只是一个评论 - 我在帖子中注意到了这一点” 是的,抱歉,我的评论有点仓促。 “你能把它作为答案发布吗?”我现在真的没有时间写一个完整的答案。 ://
标签: c++ templates inheritance inline