我无法理解DR 712

时间:2017-02-28 18:27:14

标签: c++ c++11 language-lawyer c++17 one-definition-rule

DR 712负责将{c ++ 11中[basic.def.odr] / 2的措辞改为今天的[basic.def.odr]2 and 3当前措辞。但我仍然试图了解改革的原因,如DR中所述,如下:

  

712。条件表达式的整数常量操作数是“使用?”

     

描述在类中初始化的静态数据成员   定义,9.2.3.2 [class.static.data]第3段说,

     

如果使用成员,则仍应在命名空间范围内定义该成员   在程序中...

     

“used”的定义见3.2 [basic.def.odr]第1段:

     

一个对象或非重载函数   name显示为可能评估的
  除非它是满足出现在a中的要求的对象,否则使用表达式   常量表达式(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::aS::b。该   原因是,根据5.16 [expr.cond]第4段,   这个条件表达式的结果是左值和   lvalue-to-rvalue转换应用于该转换,而不是直接转换为   对象,所以这不符合“立即应用”的要求。这是   令人惊讶和不幸,因为只有价值而不是   使用静态数据成员的地址。 (这个问题也   适用于问题696的拟议决议。)

好吧,如果“立即应用的要求失败,那么条件表达式中的表达式S::aS::b 使用(使用了odr),因此, struct S的相应静态成员需要在命名空间范围内定义。但这与DR所说的正好相反。我缺少什么?

2 个答案:

答案 0 :(得分:7)

我认为你错过了used定义的要点:

it is used UNLESS ( (const) AND (immediately applied) )

所以,如果"立即应用"是假的,那么UNLESS是假的,因此被使用了。

答案 1 :(得分:2)

  

除非[...]

,否则将使用其名称显示为可能已评估的表达式的对象或非重载函数

嗯,S::aS::b出现在f内的潜在评估表达式中。

所以他们被使用,除非以下任何一个例外适用。

  

[...]它是一个满足出现在常量表达式(5.20 [expr.const])中的要求的对象,并且立即应用左值到右值的转换(4.1 [conv.lval])。

嗯,这是一个满足出现在常量表达式中的要求的对象。所以它通过了那个测试。

但是不会立即应用左值到右值的转换。

所以它没能通过测试。

由于整个部分属于"除非",失败意味着前一种情况适用;该对象被视为"使用"。