Récemment, j'ai vu une étrange fonctionnalité C ++: un nom de classe injecté .
class X { };
X x1;
class X::X x2; // class X::X is equal to X
class X::X::X x3; // ...and so on...
Mais je ne peux pas comprendre pourquoi cette fonctionnalité est nécessaire. Existe-t-il une pratique qui nécessite cette fonctionnalité?
Et j'ai entendu dire que cette fonctionnalité n'existait pas dans l'ancien C ++. Puis, quand a-t-il été introduit? C ++ 03? C ++ 11?
Réponses:
Le nom de classe injecté signifie qu'il
X
est déclaré comme membre deX
, de sorte que la recherche de nom à l'intérieurX
trouve toujours la classe actuelle, pas une autreX
qui pourrait être déclarée dans la même portée englobante, par exempleLa
create()
fonction crée-t-elle unX
objet temporaire ou appelle-t-elle la fonctionX
? À la portée de l'espace de noms, il appellerait la fonction, donc le but du nom de classe injecté est de s'assurer que dans le corps duX
nom trouve toujours la classe elle-même (car la recherche de nom commence dans la propre portée de la classe avant de regarder dans le portée).C'est aussi utile dans les modèles de classe, où le nom de classe injecté peut être utilisé sans liste d'arguments de modèle, par exemple en utilisant simplement
Foo
au lieu de l'ID de modèle completFoo<blah, blah, blah>
, il est donc facile de se référer à l'instanciation actuelle. Voir DR 176 pour un changement entre C ++ 98 et C ++ 03 qui clarifie cela.L'idée du nom de classe injecté était présente dans C ++ 98, mais la terminologie était nouvelle pour C ++ 03.
C ++ 98 dit:
La deuxième phrase a été modifiée par DR 147 donc C ++ 03 dit dans [class] / 2:
Même avant C ++ 98, l'ARM a un libellé à peu près équivalent qui signifie que le nom de la classe peut toujours être utilisé dans le corps de la classe pour faire référence à la classe elle-même:
la source