2012-10-19 6 views
1

Je dois déclarer Iter comme typename mais pas typedef.
Alors, je ne peux pas utiliser Iter dans mon templateclass déclaration => frustrant :(
S'il vous plaît me apprendre comment utiliser Iter, ou bien me expliquer pourquoi C++ est si nasty ...classe modèle type imbriqué type nom

template <typename T> 
struct MyContainer 
{ 
    typedef std::vector<T> Vec; 
    typename Vec::iterator Iter; 

    void Fo (typename std::vector<T>::iterator); //ok 
    typename std::vector<T>::iterator Ba();  //ok 

    void Foo (Iter); //error: 'Iter' is not a type 
    Iter Bar();  //error: 'Iter' does not name a type 
};     //(gcc 4.1.2) 
  1. Pourquoi typedef ne peut pas être utilisé pour déclarer Iter? Pourquoi pas?
  2. Comment utiliser Iter dans le templateclass? (par exemple, le type de paramètre de fonction)

EDIT
Dans l'instruction typename Vec::iterator Iter; le mot-clé typename dit Vec::iterator est un type (à savoir pas une fonction/attribut de membre statique). Par conséquent, Iter n'est pas déclaré en tant que type, mais en tant que variable en utilisant le type Vec::iterator.

Répondre

7
  1. typedef peut être utilisé aux côtés typename. Ainsi, il devient:

    typedef typename vec::iterator Iter; 
    
  2. Il suffit d'utiliser Iter maintenant.

    template <typename T> 
    struct MyContainer 
    { 
        typedef std::vector<T>   Vec; 
        typedef typename Vec::iterator Iter; 
    
        void Foo (Iter); //ok 
        Iter Bar();  //ok 
    }; 
    
+0

:) parfait Je viens d'ajouter dans votre réponse la solution code source :-D merci;) – olibre

+1

@olibre En ce qui concerne votre modification à cette réponse (que j'ai annulé): Il est possible d'utiliser blockquote dans les énumérations en indentant deux fois (4 + 4 = 8 espaces). Pas besoin de syntaxe d'énumération inhabituelle ... – jogojapan

+1

@jogojapan Merci pour votre conseil/astuce :-D – olibre

1

Juste pour ajouter à la réponse précédente ...

typename Vec::iterator Iter; 

est une déclaration de C++ valide qui déclare pas un type, mais une variable nommée Iter.

Le mot-clé typename a été introduit pour spécifier que l'identificateur qui suit est un type. Lors de l'analyse Vec::iterator, le compilateur est incapable de reconnaître que iterator signifie un type, car il est un nom dépendant du modèle. Il pourrait également s'agir d'un membre de données statiques dans Vec.

Officially, what is typename for?

+0

Oui, 'typename' et' typedef' déclarent respectivement * nom de variable * et * type de variable *, n'est-ce pas? – olibre

+1

@olibre: Vous n'avez pas tout à fait raison. J'ai ajouté une explication à la réponse. – Andrey

+0

+1 Merci pour votre rappel: 'iterator' pourrait être un attribut ou une fonction ... – olibre

0

Cette ligne:

typename Vec::iterator Iter; 

déclare une variable membre appelée Iter, de type Vec::iterator (à savoir vector<T>::iterator), et non un type.

En regardant ce que vous avez fait après cela, vous vouliez probablement dire:

typedef typename Vec::iterator Iter;