Question

Je suis en train d'écrire une fonction pour imprimer une représentation des conteneurs STL communs (vecteur, liste, etc ..). J'ai donné la fonction d'un paramètre modèle T qui, par exemple, pourrait représenter vecteur. Je vais avoir des problèmes pour obtenir un itérateur de type T.

vector<int> v(10, 0);
repr< vector<int> >(v);

...

template <typename T>
void repr(const T & v)
{
    cout << "[";
    if (!v.empty())
    {
        cout << ' ';
        T::iterator i;
        for (i = v.begin(); 
             i != v.end()-1;
             ++i)
        {
            cout << *i << ", ";
        }
        cout << *(++i) << ' ';
    }
    cout << "]\n";
}

...

brett@brett-laptop:~/Desktop/stl$ g++ -Wall main.cpp
main.cpp: In function ‘void repr(const T&)’:
main.cpp:13: error: expected ‘;’ before ‘i’
main.cpp:14: error: ‘i’ was not declared in this scope
main.cpp: In function ‘void repr(const T&) [with T = std::vector<int, std::allocator<int> >]’:
main.cpp:33:   instantiated from here
main.cpp:13: error: dependent-name ‘T::iterator’ is parsed as a non-type, but instantiation yields a type
main.cpp:13: note: say ‘typename T::iterator’ if a type is meant

J'ai essayé « typename T :: iterator » comme le compilateur suggéré, mais seulement eu une erreur plus cryptique.

Edit: Merci pour l'aide les gars! Voici une version de travail pour tous ceux qui veulent utiliser cette fonction:

template <typename T>
void repr(const T & v)
{
    cout << "[";
    if (!v.empty())
    {
        cout << ' ';
        typename T::const_iterator i;
        for (i = v.begin(); 
             i != v.end();
             ++i)
        {
            if (i != v.begin())
            {
                cout << ", ";
            }
            cout << *i;
        }
        cout << ' ';
    }
    cout << "]\n";
}
Était-ce utile?

La solution

Vous avez besoin typename de dire au compilateur que ::iterator est censé être un type. Le compilateur ne sait pas que c'est un type parce qu'il ne sait pas ce que T est jusqu'à ce que vous instancier le modèle. Il pourrait également se référer à certains membres de données statiques, par exemple. C'est votre première erreur.

Votre deuxième erreur est que v est une référence-to const . Ainsi, au lieu de ::iterator vous devez utiliser ::const_iterator. Vous ne pouvez pas demander à un conteneur constant pour une iterator non const.

Autres conseils

Modifier T::iterator i; à typename T::const_iterator i; parce ::iterator est de type T et v est un const &.

Avant un type à charge admissible, vous avez besoin typename. Sans typename, il y a une règle C ++ qui analyse indique que les noms dépendants qualifiés doivent être analysés comme non-types même si elle conduit à une erreur de syntaxe.

typename indique que le nom qui suit doit être traité comme un type. Dans le cas contraire, les noms sont interprétés comme se rapportant aux non-types.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top