1

这里的这个问题引起了我的一点兴趣。C++ 标准中是否有任何地方指定必须在成员函数的任何随附实现之前解析类中的所有声明?我已经看到了一些与此类似的其他问题,但在任何答案中都没有提及该标准。

4

3 回答 3

1

[class.mem] 说:

}-2-在class-specifier结束时,类被认为是完全定义的对象类型 (3.9)(或完整类型)。在类成员规范中,类在函数体、默认参数和非静态数据成员(包括嵌套类中的此类内容)的大括号或等式初始化器中被认为是完整的。否则,它在其自己的类成员规范中被视为不完整。

为了使类在函数体中完整,通常需要解析所有声明:如果不完全解析所有声明,您将无法知道未解析的内容是否会改变含义。虽然,可能与此相关的是 [basic.scope.class]/1 它说:

3) 如果在一个类中重新排序成员声明产生了一个在 (1) 和 (2) 下的替代有效程序,该程序是非良构的,不需要诊断。

这意味着可以在不解析整个类的情况下使用某些声明,因为如果稍后的另一个声明改变了含义,那么程序将是错误的。

当然,“好像”规则允许编译器选择任何实现,只要用户无法区分,所以也许编译器可以选择解析函数体,然后根据需要解析定义,但这很难告诉处理成员函数定义需要什么(考虑一个函数调用,它可能调用几个重载函数之一,可能涉及 enable_if 类型的技巧。)

于 2012-06-07T00:34:30.380 回答
1

该标准未指定编译器应如何解析翻译单元。相反,它在任何地方都指定了使用任何标识符来引用声明并且是无效的。

3.3.2p5:

在类成员的声明点之后,可以在其类的范围内查找成员名称。[注意:即使课程是不完整的课程也是如此。]

3.3.7p1:

以下规则描述了类中声明的名称范围。

  1. 类中声明的名称的潜在范围不仅包括名称声明点之后的声明区域,还包括所有函数体、非静态数据成员的大括号或等号初始化器以及其中的默认参数类(包括嵌套类中的此类内容)。
  2. N类中使用的名称S应在其上下文中引用相同的声明,并且在完成的范围内重新评估时S。违反此规则不需要诊断。
  3. 如果对类中的成员声明重新排序会在 (1) 和 (2) 下产生一个替代的有效程序,则该程序是格式错误的,不需要诊断。
  4. 在成员函数中声明的名称隐藏了同名的声明,其范围扩展到或超过成员函数类的末尾。
  5. 延伸到或超过类定义结尾的声明的潜在范围也延伸到由其成员定义定义的区域,即使成员是在类外部的词法定义的(这包括静态数据成员定义、嵌套类定义、成员函数定义(包括成员函数体和在declarator-id之后的此类定义的声明部分的任何部分,包括参数声明子句和任何默认参数(8.3.6)。
于 2012-06-07T00:35:14.783 回答
0

这是解释 C++ 编程语言标准的草案。

编程语言 C++ PDF

我认为第 220 页对成员函数有一些解释。

于 2012-06-07T00:34:08.403 回答