N3936的3.3.7 / 1节中的规则3是多余的吗?

时间:2014-11-05 15:51:38

标签: c++ scope language-lawyer c++14

我最近answered a question处理了违反draft C++14 standard: N4140部分3.3.7 类范围段落1规则2的问题,其中说明:

  

类S中使用的名称N应引用其中的相同声明   上下文,并在完成范围内重新评估   违反此规则需要诊断。

当时规则3似乎也很重要,它说:

  

如果在类中重新排序成员声明会产生备用有效   根据(1)和(2)的程序,该程序是不正确的,没有诊断   必需的。

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

规则3是多余的,还是有一些需要两个规则的边缘情况?

1 个答案:

答案 0 :(得分:7)

根据Defect Report 1875: Reordering declarations in class scope规则3是多余的,建议的解决方案是删除规则3,它说:

  

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

,建议的解决方案是:

  

删除3.3.7 [basic.scope.class]第1段和第3段的第3项   重新编号后续项目

虽然这个缺陷报告似乎证实了我最初的怀疑,但我仍然有一种唠叨的感觉,或许规则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不适用于Casey在评论中提到的这个例子:

class X { int a; int b; };

因为即使有多个有效排序,这种情况也不属于规则12规则3所要求的范围:

  

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