【问题标题】:I just can not understand DR 712我就是看不懂 DR 712
【发布时间】: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::aS::b。这 原因是,根据 5.16 [expr.cond] 第 4 段, 这个条件表达式的结果是一个左值并且 左值到右值的转换应用于那个,而不是直接应用于 对象,所以这不符合“立即应用”的要求。这是 令人惊讶和不幸,因为只有价值观而不是 使用静态数据成员的地址。 (这个问题也 适用于问题 696 的提议解决方案。)

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

【问题讨论】:

  • 原来的措辞是说某些东西是 odr-used unless ... l2r 被立即应用,并且由于S::aS::b 没有立即受到 l2r (只有条件表达式是),它们 odr-used,因为“除非”部分不适用。

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


【解决方案1】:

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

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

所以,如果“立即应用”为假,那么 UNLESS 为假,因此使用它。

【讨论】:

  • 是的,你是对的。必须满足这两个条件才能不使用该对象。
【解决方案2】:

使用名称显示为潜在求值表达式的对象或非重载函数,除非[...]

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

因此使用它们,除非以下任何一个例外适用。

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

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

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

所以它没有通过测试。

由于这整个部分都在“除非”下,因此失败意味着前一种情况适用;该对象被视为“已使用”。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-07-20
    • 1970-01-01
    • 2022-01-10
    • 2023-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多