我最近回答了一个关于违反草案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 };
};
这违反了规则2
和3
只是一个小调整:
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( 下的备用有效程序