25

C++14 草案 (N3936) 在 §3.2/3 中指出:

变量 x 的名称显示为潜在求值表达式 ex 是 odr-used 除非将左值到右值转换 (4.1) 应用到 x 产生不调用任何非平凡函数的常量表达式 (5.19),并且,如果x 是一个对象,ex 是表达式 e 的潜在结果集合中的一个元素,其中左值到右值的转换(4.1)应用于 e,或者 e 是丢弃值表达式(第 5 条)。

这对我来说没有任何意义:如果表达式e丢弃值表达式取决于使用的上下文e表达式语句(第 6.2 节)中使用的每个表达式都是废弃值表达式。是否应用左值到右值转换e也取决于使用的上下文e

此外,一个表达式位于另一个表达式的潜在结果集中意味着什么。一个人需要一个表达式相等的概念才能确定一个集合的成员。但是我们没有参考透明度,所以我看不出这是如何实现的。

为什么从 C++11 更改为 C++14?这应该如何解释?就目前而言,这没有意义。

4

1 回答 1

27

odr使用的目的

非正式地,变量的odr 使用意味着以下内容:

如果程序中任何地方的任何表达式直接获取对象的地址或将引用绑定到对象,则必须定义该对象。

最新草案中的澄清

在最新版本的规范中,第 3.2 条已得到澄清(参见GitHub 上的 C++14 草案):

2 一个表达式可能会被计算,除非它是一个未计算的操作数(第 5 条)或其子表达式。表达式的潜在结果集e定义如下:

  • 如果e是 id 表达式 (5.1.1),则该集合仅包含e.
  • 如果e是类成员访问表达式(5.2.5),则该集合包含对象表达式的潜在结果。
  • Ife是一个指向成员的表达式 (5.5),其第二个操作数是一个常量表达式,该集合包含对象表达式的潜在结果。
  • 如果e具有 (e1) 形式,则该集合包含 e1 的潜在结果。
  • Ife是一个泛左值条件表达式 (5.16),该集合是第二个和第三个操作数的潜在结果集合的并集。
  • Ife是一个逗号表达式 (5.18),该集合包含右操作数的潜在结果。
  • 否则,集合为空。

[注意:这个集合是一个(可能是空的)id-expressions 集合,每e一个都是e.

[ 示例:在以下示例中,初始化程序的潜在结果集n包含第一S::x个子表达式,但不包含第二S::x个子表达式。

struct S { static const int x = 0; };
const int &f(const int &r);
int n = b ? (1, S::x) // S::x is not odr-used here
          : f(S::x);  // S::x is odr-used here, so
                      // a definition is required

—结束示例] —结束说明]

3x名称显示为潜在求值表达式的变量ex被 odr 使用ex除非应用左值到右值转换 (4.1) 以x生成不调用任何非平凡函数的常量表达式 (5.19),并且如果x是对象,ex是表达式 的潜在结果集合中的一个元素e,其中左值到右值的转换 (4.1) 应用于e,或者e是丢弃值表达式(第 5 条)。

C++11 的情况如何?

C++11 中的 §3.2/2 内容如下:

一个表达式可能被求值,除非它是一个未求值的操作数(第 5 条)或其子表达式。名称显示为潜在求值表达式的变量是 odr-used 的,除非它是一个满足出现在常量表达式 (5.19) 中的要求并且立即应用左值到右值转换 (4.1) 的对象。

这些措辞的问题是DR 712。考虑这个例子:

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是左值,所以条件表达式x ? S::a : S::b也是左值。这意味着左值到右值的转换不会立即应用于S::aand S::b,而是应用于条件表达式的结果。这意味着按照 C++11 的措辞,这些静态数据成员是 odr-used 并且需要定义。但实际上只使用了值,因此不需要定义静态数据成员 - 声明就足够了。C++14 草案的新措辞解决了这个问题。

新措辞是否解决了所有问题?

否。在以下示例中,该变量S::a仍然是 odr-used:

struct S { static constexpr int a[2] = {0, 1}; };
void f() {
    auto x = S::a[0];
}

因此,我提交了一个新问题,将以下项目符号添加到 §3.2/2:

  • 如果e是形式的泛左值下标表达式(5.2.1)E1[E2],则集合包含 的潜在结果E1
于 2014-05-14T12:44:26.810 回答