Why is there an injected class name?

C++

C++ Problem Overview


Recently, I saw a strange C++ feature: injected class name.

class X { };
X x1;
class X::X x2; // class X::X is equal to X
class X::X::X x3; // ...and so on...

But I cannot figure out why this feature is necessary. Is there any practice that requires this feature?

And I heard this feature didn't exist in old C++. Then, when was it introduced? C++03? C++11?

C++ Solutions


Solution 1 - C++

The injected class name means that X is declared as a member of X, so that name lookup inside X always finds the current class, not another X that might be declared at the same enclosing scope, e.g.

void X() { }
class X {
public:
  static X create() { return X(); }
};

Is the create() function creating a temporary X object or calling the function X? At namespace scope it would call the function, so the purpose of the injected-class-name is to ensure that within the body of X the name always finds the class itself (because name lookup starts in the class' own scope before looking in the enclosing scope).

It's also helpful inside class templates, where the injected class name can be used without a template argument list, e.g. using simply Foo instead of the full template-id Foo<blah, blah, blah>, so it's easy to refer to the current instantiation. See DR 176 for a change between C++98 and C++03 that clarified that.

The idea of the injected class name was present in C++98, but the terminology was new for C++03.

C++98 says:

> A class-name is inserted into the scope in which it is declared immediately after the class-name is seen. The class-name is also inserted into the scope of the class itself.

The second sentence was changed by DR 147 so C++03 says in [class]/2:

> A class-name is inserted into the scope in which it is declared immediately after the class-name is seen. The class-name is also inserted into the scope of the class itself; this is known as the injected-class-name.

Even before C++98, the ARM has roughly equivalent wording that means the class' name can always be used in the class body to refer to the class itself:

> The name of a class can be used as a class-name even within the member-list of the class specifier itself. >> * For example,
>>> class link { link* next; };

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionikhView Question on Stackoverflow
Solution 1 - C++Jonathan WakelyView Answer on Stackoverflow