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
X
se declara como miembro deX
, por lo que la búsqueda de nombres en el interiorX
siempre encuentra la clase actual, no otraX
que pueda declararse en el mismo ámbito de cobertura, por ejemplo¿La
create()
función está creando unX
objeto 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 delX
nombre 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
Foo
lugar 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