【发布时间】:2013-01-10 23:05:36
【问题描述】:
这可能是一个不寻常的问题,因为它要求对another question 的简短回答以及与之相关的 C++11 标准的某些方面进行更全面的解释。
为了便于参考,我将在这里总结参考的问题。 OP 定义了一个类:
struct Account
{
static constexpr int period = 30;
void foo(const int &) { }
void bar() { foo(period); } //no error?
};
并且想知道为什么他对类内初始化静态数据成员的使用没有错误(一本书提到这是非法的)。 Johannes Schaub 的回答指出:
- 这违反了单一定义规则;
- 不需要诊断。
尽管我依赖这个答案的来源和有效性,但我真的不喜欢它,因为我个人觉得它太神秘了,所以我试图自己想出一个更有意义的答案,但只取得了部分成功。相关似乎是§ 9.4.2/4:
"在程序中odr-used (3.2) 的静态数据成员应该只有一个定义;不需要诊断" [重点是我的]
这让我更接近重点。这就是第 3.2/2 节定义 odr-used 变量的方式:
“名称显示为潜在求值表达式的变量是 odr-used 除非它是一个满足出现在常量表达式中的要求的对象 (5.19) 并且立即应用左值到右值转换(4.1)” [重点是我的]
在OP的问题中,变量period显然满足出现在常量表达式中的要求,是constexpr变量。所以肯定要在秒条件中找到原因:“并且立即应用左值到右值转换(4.1)”。
这是我在解释标准时遇到困难的地方。 这第二个条件实际上是什么意思?它涵盖了哪些情况?这是否意味着如果从函数返回静态constexpr 变量不 odr-used(因此可以在类内初始化)?
更笼统地说:您可以对静态 constexpr 变量做什么,以便在课堂上初始化它?
【问题讨论】:
-
我看到我们有很多relevant yet distinct questions。两者都来自相同的基础 Q 和答案 :)
-
@AlokSave:确实如此。至少我不是唯一一个觉得整个事情有点混乱的人。
-
老实说,为了理解标准,我做了一些挠头,但我无法真正看透它。实际上,您在整个过程中都很好地表达了思考过程question.Me 我提出了一个更笼统的问题,担心我对标准语的看法可能会影响阅读它的人是否有意义。 +1 用于记录您的研究:)
-
@AlokSave:我喜欢“担心我对标准语的看法实际上可能会影响阅读它的人的意义”部分。几乎每次我不得不询问一些对我来说晦涩难懂的正式定义的含义时(不仅仅是在 C++ 或编程中),我都会遇到这种感觉。
-
我没有将“神秘”术语“一个定义规则”放入我的答案中。只有当有人出于某种原因想知道我提到的规则在标准中的位置时,我才提到它。
标签: c++ c++11 static-members constexpr one-definition-rule