【发布时间】:2021-06-03 15:15:07
【问题描述】:
我试图更好地了解模板类/结构中静态成员的初始化。
让我们看下面的最小示例(在Coliru 中可用):
#include <iostream>
struct A {
int value;
A(int val) : value{val} { std::cout << "A(" << value << ")\n"; }
};
struct Static {
static inline A s_a{42};
static void use() {
std::cout << s_a.value++ << '\n';
std::cout << s_a.value << '\n';
}
};
struct User {
User() {
Static::use();
}
};
User s_user{};
int main() {
return 0;
}
输出是(如我所料):
A(42)
42
43
现在,我希望能够为不同类型提供多个版本的Static,因此我将其转换为模板(Coliru):
#include <iostream>
struct A {
int value;
A(int val) : value{val} { std::cout << "A(" << value << ")\n"; }
};
template<class T>
struct Static {
static inline A s_a{42};
static void use() {
std::cout << s_a.value++ << '\n';
std::cout << s_a.value << '\n';
}
};
struct User {
User() {
Static<int>::use();
}
};
User s_user{};
int main() {
return 0;
}
然后输出是
0
1
A(42)
如您所见,A::value 未初始化使用,A 的构造函数在Static<int>::use 执行后调用。
我可以更改s_a 的定义,使其专门用于高级:
template<class T>
struct Static {
static A s_a;
// ...
};
template<> A Static<int>::s_a{42};
它可以正常工作 (Coliru)。对应的是我必须定义每一个专业化,我想让它尽可能容易使用(你可以假设实际代码更复杂)。
所以,我的问题是:
-
为什么
Static<T>::use()在它(s_a)被初始化之前使用s_a?我可以考虑某种延迟初始化直到专业化(对不起,不知道它的正确名称),并且User<正在调用一个静态函数,不知何故,与静态属性(只是它们在同一个封装中),但我不知道确切的原因,也不知道标准对此有何规定。 -
我应该如何更改此代码以获得与非模板版本相同的行为?也就是说,任何
Static<T>的属性都可以在调用其静态方法之前进行初始化。
注意:struct A 只是这里的一个最小示例,在我正在处理的项目中,它是一个基于 Static<T> 的模板化类。
【问题讨论】:
标签: c++ templates static initialization c++17