【发布时间】:2017-07-19 20:41:40
【问题描述】:
DR 712 负责将 C++11 中的 [basic.def.odr]/2 的措辞更改为今天在[basic.def.odr]2 and 3 中的当前措辞。但我仍在尝试了解更改的原因,如 DR 中所述,如下所示:
712。是否“使用了条件表达式的整数常量操作数”?
在描述类内部初始化的静态数据成员 定义,9.2.3.2 [class.static.data] 第 3 段说,
如果使用该成员,则仍应在命名空间范围内定义 在程序中...
“使用”的定义在 3.2 [basic.def.odr] 第 1 段:
一个对象或非重载函数,其 名称显示为潜在评估
除非它是一个满足出现在 常量表达式 (5.20 [expr.const]) 和左值到右值的转换 (4.1 [conv.lval])
立即应用。现在考虑以下示例:
struct S { static const int a = 1; static const int b = 2; }; int f(bool x) { return x ? S::a : S::b; }根据标准的当前措辞,这个例子 要求在命名空间范围内定义
S::a和S::b。这 原因是,根据 5.16 [expr.cond] 第 4 段, 这个条件表达式的结果是一个左值并且 左值到右值的转换应用于那个,而不是直接应用于 对象,所以这不符合“立即应用”的要求。这是 令人惊讶和不幸,因为只有价值观而不是 使用静态数据成员的地址。 (这个问题也 适用于问题 696 的提议解决方案。)
好吧,如果“立即应用的要求”失败,那么条件表达式中的表达式S::a 和S::b 将不 使用(odr-used),因此,相应的静态成员struct S 的不需要需要在命名空间范围内定义。但这与 DR 所说的完全相反。我错过了什么???
【问题讨论】:
-
原来的措辞是说某些东西是 odr-used unless ... l2r 被立即应用,并且由于
S::a和S::b没有立即受到 l2r (只有条件表达式是),它们被 odr-used,因为“除非”部分不适用。
标签: c++ c++11 language-lawyer c++17 one-definition-rule