这个问题here引起了我的兴趣。 C ++标准中是否有任何地方指定在成员函数的任何附带实现之前,必须解析类中的所有声明?我已经看到了一些与此相似的其他问题,但在任何答案中都没有提到标准。
答案 0 :(得分:1)
[class.mem]说:
-2-在类说明符的结束
}
处,类被视为完全定义的对象类型(3.9)(或完整类型)。在类 member-specification 中,对于非静态数据成员,该类在函数体,默认参数和 brace-or-equal-initializers 中被视为完整(包括嵌套类中的这类东西)。否则,它在其自己的类 member-specification 中被视为不完整。
对于要在函数体内完成的类,通常需要解析所有声明:如果没有完全解析所有声明,则无法知道未解析的内容是否会改变含义。虽然可能与[basic.scope.class] / 1相关,但是:
3)如果类中的重新排序成员声明在(1)和(2)下产生备用有效程序,则程序格式错误,不需要诊断。
这意味着可以在不解析整个类的情况下使用某些声明,因为如果另一个后来的声明改变了含义,那么程序就会形成错误。
当然“似乎”规则允许编译器选择任何实现,只要用户无法区分,所以编译器可能选择解析函数体然后解析根据需要定义,但很难说出处理成员函数定义需要什么(考虑一个可能调用多个重载函数之一的函数调用,可能涉及enable_if-type技巧。)
答案 1 :(得分:1)
标准没有规定编译器应如何解析翻译单元。相反,它指定它在任何地方,并且无效使用任何标识符来引用声明。
3.3.2p5:
在声明类成员之后,可以在其成员范围内查找成员名称 类。 [注意:即使班级是不完整的班级,也是如此。 ]
3.3.7p1:
以下规则描述了在类中声明的名称范围。
- 在类中声明的名称的潜在范围不仅包括名称声明点后面的声明性区域,还包含所有函数体,非em的 brace-or-equal-initializers 。 -static数据成员,以及该类中的默认参数(包括嵌套类中的这些内容)。
- 类
N
中使用的名称S
应在其上下文中引用相同的声明,并在S
的已完成范围内重新评估。违反此规则无需诊断。- 如果某个类中的重新排序成员声明在(1)和(2)下产生备用有效程序,则该程序格式错误,无需诊断。
- 在成员函数中声明的名称隐藏了一个同名的声明,其范围扩展到或超过了成员函数类的末尾。
- 扩展到或超过类定义结尾的声明的潜在范围也扩展到由其成员定义定义的区域,即使成员是在类之外的词法上定义的(这包括静态数据成员定义,嵌套类定义,成员函数定义(包括成员函数体和此类定义的声明器部分的任何部分,它们遵循 declarator-id ,包括parameter-declaration-clause和任何默认参数(8.3。 6)。
醇>
答案 2 :(得分:0)