我正在阅读c ++ 14 N3797,而我在3.3.7 / 1中遇到过:
如果在类中重新排序成员声明会产生备用有效 根据(1)和(2)的程序,该程序是不正确的,没有诊断 必需的。
有(1)和(2):
1)类中声明的名称的潜在范围不仅包括在内 名称的声明点后的声明区域, 而且所有函数体,默认参数, 异常规范,以及支持或等于初始化的 该类中的非静态数据成员(包括嵌套中的这些内容) 类)。
2)S类中使用的名称N应引用同一声明 它的背景以及在S的完整范围内重新评估的情况 违反此规则需要诊断。
如果我们写下以下内容:
class A
{
int a;
int b;
}
然后程序就是格格不入。重新成员声明会产生另一个有效的程序:
class A
{
int b;
int a;
}
我可能不能正确理解这条规则吗?
答案 0 :(得分:18)
"备用有效程序"指的是这样一种情况,即类中元素的每个排序都会产生对程序的有效解释,但的含义会根据顺序改变。
在您的情况下,允许更改a
和b
的顺序,但是,因为它们的相对顺序不会影响程序的含义,行为是定义的。
为此,您必须在类中使用已在类外部定义其他含义的名称。例如:
typedef void *T;
struct whatever {
T a;
typedef long T;
};
此处,a
声明的相对顺序和T
的typedef会影响代码的含义。正如它现在所写,a
的类型为void *
,因为全局typedef void *T;
在解析T a;
时属于范围。
但是,如果我们将这两者重新排列为:
typedef void *T;
struct whatever {
typedef long T;
T a;
};
... T a;
相当于long a;
。由于两个声明的相对顺序,程序的含义是不同的,因此行为是未定义的。