Apparently Obstacle is just a class.
Amazingly, the following also works, tested in g++ 4.2, g++ 4.3, g++ 4.4, clang++ 2.9, and clang++ 3.1:
std::vector<Obstacle::Obstacle::Obstacle::Obstacle::Obstacle*> obstacles;
Multiple versions of g++ and multiple versions of clang compiled the above.
g++ 4.5 and 4.6 have problems with this construct. This looks like a g++ bug, versions 4.5 and higher. So why should this be legal?
This is a bug in pre 4.5 g++, clang, and apparently other compilers. The relevant portion of the standard is 3.4.3.1, para 1a:
If the nested-name-specifier nominates a class C, and the name specified after the nested-name-specifier, when looked up in C, is the injected-class-name of C (clause 9), the name is instead considered to name the constructor of class C. Such a constructor name shall be used only in the declarator-id of a constructor definition that appears outside of the class definition.
In other words, Obstacle::Obstacle is illegal except when used in an out of line definition of a constructor for class Obstacle.
So how are these compilers parsing this? Those compilers are treating Obstacle::Obstacle as having special meaning only in the case of an out of line definition of a constructor. Otherwise, Obstacle::Obstacle follows the injected name rules, but ignore the fact that that rule does not apply here. Obstacle::Obstacle* isn't a pointer to the constructor because constructors don't have names. Obstacle::Obstacle* instead means whatever Obstacle* means when evaluated from within the context of the class Obstacle. But inside the class, Obstacle* is still a pointer to an instance of class Obstacle. Obstacle::Obstacle* is just an Obstacle*, as is Obstacle::Obstacle::Obstacle*, and so on. Pile on as many Obstacles you want and it's still just an Obstacle*.