Recientemente, vi una extraña característica de C ++: nombre de clase inyectado .
class X { };
X x1;
class X::X x2; // class X::X is equal to X
class X::X::X x3; // ...and so on...
Pero no puedo entender por qué esta característica es necesaria. ¿Hay alguna práctica que requiera esta función?
Y escuché que esta característica no existía en el antiguo C ++. Entonces, ¿cuándo fue presentado? C ++ 03? C ++ 11?

Respuestas:
El nombre de la clase inyectada significa que
Xse declara como miembro deX, por lo que la búsqueda de nombres en el interiorXsiempre encuentra la clase actual, no otraXque pueda declararse en el mismo ámbito de cobertura, por ejemplo¿La
create()función está creando unXobjeto temporal o está llamando a la funciónX? En el ámbito del espacio de nombres llamaría a la función, por lo que el propósito del nombre de la clase inyectada es garantizar que dentro del cuerpo delXnombre siempre encuentre la clase en sí misma (porque la búsqueda de nombres comienza en el propio ámbito de la clase antes de buscar en el adjunto alcance).También es útil dentro de las plantillas de clase, donde el nombre de la clase inyectada se puede usar sin una lista de argumentos de plantilla, por ejemplo, usando simplemente en
Foolugar de la plantilla completa de identificaciónFoo<blah, blah, blah>, por lo que es fácil referirse a la instanciación actual. Ver DR 176 para un cambio entre C ++ 98 y C ++ 03 que lo aclaró.La idea del nombre de la clase inyectada estaba presente en C ++ 98, pero la terminología era nueva para C ++ 03.
C ++ 98 dice:
El DR 147 cambió la segunda oración, por lo que C ++ 03 dice en [clase] / 2:
Incluso antes de C ++ 98, el ARM tiene una redacción más o menos equivalente que significa que el nombre de la clase siempre se puede usar en el cuerpo de la clase para referirse a la clase misma:
fuente