N3.3.7/1 节中的规则 3936 是否多余



我最近回答了一个关于违反草案C++14标准的问题:N4140 第 3.3.7 类范围部分 1规则 2 的段落说:

S类中使用的名称N应指其中的同一声明 上下文以及在 S. No 的已完成范围内重新评估时 违反此规则需要诊断。

当时的规则3似乎也很相关,它说:

如果对类中的成员声明重新排序会产生备用有效 (1(和(2(下的程序,程序格式不正确,没有诊断 必填。

我的第一反应是,第3条规则似乎是多余的,实际上只是对规则2的澄清,并不涵盖尚未涵盖的任何情况。导致备用有效程序的重新排序也必须违反规则 2

那么规则3是多余的,还是有一些边缘情况需要同时使用这两个规则?

根据缺陷

报告 1875: 在类范围规则3中重新排序声明是多余的,建议的解决方案是删除规则3,它说:

规则#3的必要性尚不清楚;似乎任何 否则有效的重新排序必须违反规则 #2 才能 产生不同的解释。从字面上看,规则#3也将 适用于简单地对没有名称的非静态数据成员重新排序 完全依赖关系。可以简单地删除吗?

建议的解决方案是:

删去3.3.7[基本范围.class]第1款第三项和 对后续项目重新编号

虽然这份缺陷报告似乎证实了我最初的怀疑,但我有一种唠叨的感觉,也许规则3毕竟要宽泛一些。第 3.3.7 节包括以下示例:

enum { i = 1 };
class X {
  char v[i]; // error: i refers to ::i
             // but when reevaluated is X::i
  int f() { return sizeof(c); } // OK: X::c
  char c;
  enum { i = 2 };
};

这违反了规则23只是一个小调整:

enum { i = 1 };
class X {
  enum { i = 2 };
  char v[i];  // no longer refers to ::i 
              // but reordering can cause it to refer to ::i again
  int f() { return sizeof(c); } // OK: X::c
  char c;
};

似乎不再违反规则2但肯定似乎违反了规则3。我认为这个代码示例很麻烦,因为成员的重新排序很容易导致代码违反规则 2 返回,但不需要诊断来指示这一点,这使得这段代码相当脆弱。

更新

据我了解,规则3不适用于凯西在评论中提到的这个例子:

class X { int a; int b; };

因为即使有多个有效的排序,这种情况也不属于规则1和规则3要求的2

(1( 和 (2( 下的备用有效程序

最新更新