Propagation de ‘typedef’ à partir d’une classe dérivée pour ‘template’

J’essaie de définir la classe de base, qui contient uniquement des typedef.

template class A { public: typedef std::vector Vec_t; }; template class B : public A { private: Vec_t v; // fails - Vec_t is not recognized }; 

Pourquoi dans BI recevoir une erreur que Vec_t n’est pas reconnu et je dois l’écrire explicitement?

 typename A::Vec_t v; 

Je crois que cette question est en double, mais je ne peux pas la trouver maintenant. C ++ Standard dit que vous devez qualifier complètement le nom selon 14.6.2 / 3:

Dans la définition d’un modèle de classe ou d’un membre d’un modèle de classe, si une classe de base du modèle de classe dépend d’un paramètre de modèle, la scope de la classe de base n’est pas examinée lors de la recherche de nom non qualifiée. template ou member ou lors d’une instanciation du modèle de classe ou du membre.

UPD: J’ai finalement trouvé le doublon: le voici .

Il y a quelque chose appelé des noms dépendants et non dépendants dans le cas des modèles.

Si name dépend du paramètre template T, son nom dépendant et les autres qui ne dépendent pas du paramètre T sont des noms indépendants .

Voici la règle: le compilateur ne cherche pas dans les classes de base dépendantes (comme A) lors de la recherche de noms non dépendants (comme Vec_t). Par conséquent, le compilateur ne sait même pas qu’ils existent, encore moins sont des types.

Le compilateur ne peut pas supposer que Vec_t est un type jusqu’à ce qu’il connaisse T car il existe une spécialisation potentielle de AA:: Vec_t est un membre de données

Donc, la solution est d’utiliser typename

  typename A::Vec_t v; ← good 

Je vous recommande de passer par https://isocpp.org/wiki/faq/templates#nondependent-name-lookup-types .

Ancien lien (cassé): http://www.parashift.com/c++-faq-lite/templates.html#faq-35.18

Parce que le compilateur n’est pas certain que Vec_t nomme un type. Par exemple, A pourrait être spécialisé pour que T=int n’ait pas ce typedef particulier.

Vous devez qualifier explicitement l’utilisation de Vec_t car le compilateur ne sait pas d’où vient Vec_t .

Il ne peut rien supposer de la structure de A, puisque le modèle de classe A peut être spécialisé. La spécialisation peut inclure un Vec_t qui n’est pas un typedef, ou même pas inclure un membre Vec_t .

Vec_t n’est pas un nom dépendant, et le compilateur doit savoir ce que c’est sans instancier de modèles (classe de base dans ce cas). Ce n’est vraiment pas différent de:

 template  class X { std::ssortingng s; } 

Ici aussi, le compilateur doit connaître std :: ssortingng même si X n’est pas instancié, car le nom ne dépend pas de l’argument de modèle T (pour autant que le compilateur puisse le supposer).

Dans l’ensemble, les typedefs dans une classe de base de modèle semblent plutôt inutiles pour une utilisation dans une classe dérivée. Les typedefs sont utiles pour l’utilisateur, cependant.

Ce concept peut être associé à la façon dont nous utilisons std::vector . Par exemple, si nous avons un std::vector Foo . Maintenant, nous décidons d’utiliser l’un de ses types de membres, disons un iterator . Dans ce scénario, nous mentionnons explicitement

 std::vector::iterator foo_iterator; 

De même, dans votre cas, pour utiliser un type de membre public Vec_t du template class A , vous devez le déclarer explicitement comme

 A::Vec_t v; OR A::Vec_t int_type;