Static member initialization in a class template
我想这样做:
1 2 3 4 5 6
| template <typename T>
struct S
{
...
static double something_relevant = 1.5;
}; |
但我不能,因为something_relevant不是整型的。它不依赖于T,但现有的代码依赖于它是S的静态成员。
因为S是模板,所以我不能将定义放在编译文件中。我该如何解决这个问题?
- Also Applies to EDOCX1 English 0 Type
- 自C++11 The keyword inline has changed so that static variables can be initialized at the point of Declaration.So the declaration for this would look like"inline static double some thing"U relevant=1.5;"
只需在标题中定义它:
1 2 3 4 5 6 7 8
| template <typename T>
struct S
{
static double something_relevant;
};
template <typename T>
double S<T>::something_relevant = 1.5; |
由于它是模板的一部分,与所有模板一样,编译器将确保只定义一次。
- @SBI:这不是违反了一个定义规则吗?
- 不,如果我们说的是模板,就不会。否则函数模板也会这样做。
- @斯比,@prason:事实上,prason似乎是第一个。但我仍然接受SBI,因为我对ODR的评论(这是我最关心的问题)。
- @约翰内斯:你在准确的时间怎么办?对我来说,它只显示"1小时前"每个。我知道我可以按"最早"和"最新"对它们进行排序,它将在三天内显示确切的时间(直到那时它显示"2天前"),但我不知道我现在是如何得到确切的时间的。
- @SBI将鼠标悬停在文本上:)
- @Johannes Schaub-Litb:坦率地说,当我看到SBI的答案时,最后两行是template double something_relevant = 1.5;,这在语法上是不正确的(他可能漏掉了一些东西);-。所以我决定发布我的解决方案。
- @斯比:如果你认为我上次的评论有什么问题,请一定要提到:—)
- @约翰内斯:该死,我在这里一年了,我不知道!我还缺什么?(我仍然记得当我发现当我点击投票数时出现的两个数字不是错误,而是一个特性时的耻辱。)哇,当我悬停在你的名字上时,我看到了你的代表!我也不知道那个。@不,你是对的,我迭代地到达了它现在的位置。(这就是为什么我投了你的票,顺便说一句)
- @约翰内斯:啊,我一直想知道这代表什么。(是的,想象一下这是一首美妙的歌。)@james:that响铃:"我的发型立即使我所有的判断受到质疑。"(接近那篇文章的结尾)
- 如果类被封装到名称空间中怎么办?
- @FNC12:那么你需要把东西放到所说的名称空间中吗?
- @SBI-为了混水,我们如何初始化T的5或6个专门化?在如何初始化参数化模板类的静态成员时,我一直在尝试简单明显的答案,但由于多个定义的符号,Clang不断失败链接,因为头在多个源文件中使用。在我们的例子中,类变量是static const,它就像是逃离了翻译单元范围。
- @JWW:如果您定义特定实例的静态成员,而不是基本模板的静态成员,则必须将其放入CPP文件中。有一些技巧可以解决这个问题,但是它们会给你的代码增加难以理解的缺点。
这会起作用
1 2 3 4 5 6 7 8 9
| template <typename T>
struct S
{
static double something_relevant;
};
template<typename T>
double S<T>::something_relevant=1.5; |
由于C++ 17,现在可以将静态成员声明为EDCOX1(0),它将定义类定义中的变量:
1 2 3 4 5 6
| template <typename T>
struct S
{
...
static inline double something_relevant = 1.5;
}; |
现场:https://godbolt.org/g/bgsw1u
- 这是一个很好的答案。简短而精确。有关详细信息,请参阅en.cppreference.com/w/cpp/language/static static data _member&zwnj;&8203;s。