显然Obstacle
只是一个类。
令人惊讶的是,在 g++ 4.2、g++ 4.3、g++ 4.4、clang++ 2.9 和 clang++ 3.1 中测试的以下内容也有效:
std::vector<Obstacle::Obstacle::Obstacle::Obstacle::Obstacle*> obstacles;
多个版本的g++和多个版本的clang编译如上。
g++ 4.5 和 4.6 有这个结构的问题。这看起来像一个 g++ 错误,版本 4.5 及更高版本。那么为什么这应该是合法的呢?
这是 pre 4.5 g++、clang 和显然其他编译器中的错误。标准的相关部分是 3.4.3.1,第 1a 段:
如果 nested-name-specifier 指定了一个类 C,并且在 nested-name-specifier 之后指定的名称,当在 C 中查找时,是 C 的注入类名(第 9 条),则该名称被认为是命名类 C 的构造函数。这样的构造函数名称只能用于出现在类定义之外的构造函数定义的 declarator-id 中。
换句话说,Obstacle::Obstacle
是非法的,除非在 class 的构造函数的外部定义中使用Obstacle
。
那么这些编译器是如何解析这个的呢?那些编译器Obstacle::Obstacle
仅在构造函数的定义异常的情况下才被视为具有特殊含义。否则,Obstacle::Obstacle
遵循注入的名称规则,但忽略该规则不适用于此处的事实。Obstacle::Obstacle*
不是指向构造函数的指针,因为构造函数没有名称。Obstacle::Obstacle*
相反,意味着Obstacle*
从类的上下文中评估时的任何方法Obstacle
。但在类内部,Obstacle*
仍然是一个指向类实例的指针Obstacle
。Obstacle::Obstacle*
只是一个Obstacle*
, as is Obstacle::Obstacle::Obstacle*
, 等等。堆上尽可能多Obstacle
的 s,它仍然只是一个Obstacle*
.