我无法理解DR 712

Joã*_*nso 8 c++ one-definition-rule language-lawyer c++11 c++17

DR 712负责将[basic.def.odr]/2中的[basic.def.odr]/2的措辞改为当前的措辞,在[basic.def.odr] 2和3中.但我仍然试图了解改革的原因,如DR所述,如下:

712.条件表达式的整数常量操作数是"使用?"

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

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

"used"的定义见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;
 }
Run Code Online (Sandbox Code Playgroud)

根据标准的当前措辞,此示例要求S::aS::b在命名空间范围内定义.这样做的原因是,根据5.16 [expr.cond]第4段,这个条件表达式的结果是一个左值,并且左值到右值的转换应用于它,而不是直接应用于对象,所以这个失败"立即申请"的要求.这是令人惊讶和不幸的,因为仅使用静态数据成员的值而不是地址.(这个问题也适用于议题696的拟议决议.)

那么,如果"立即应用要求失败,则表达式S::aS::b在条件表达式使用(ODR使用的),等等,各自的静态成员struct S需要在命名空间范围中定义.但是,这是完全DR正在说什么.我错过了什么?

agh*_*ast 7

我想你错过了used定义的重点:

it is used UNLESS ( (const) AND (immediately applied) )
Run Code Online (Sandbox Code Playgroud)

因此,如果"立即应用"为假,则UNLESS为假,因此使用它.