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])
立即应用.现在考虑以下示例:
Run Code Online (Sandbox Code Playgroud)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使用的),等等,各自的静态成员struct S将不需要在命名空间范围中定义.但是,这是完全DR正在说什么.我错过了什么?
我想你错过了used定义的重点:
it is used UNLESS ( (const) AND (immediately applied) )
Run Code Online (Sandbox Code Playgroud)
因此,如果"立即应用"为假,则UNLESS为假,因此使用它.