Domanda

Sto cercando di scrivere una funzione per stampare una rappresentazione dei contenitori comuni STL (vettore, lista, ecc ..). Ho dato la funzione di un parametro di template T, che, per esempio, potrebbe rappresentare vettore. Sto avendo problemi per ottenere un iteratore di tipo 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

ho provato 'typename T :: iterator' come il compilatore ha suggerito, ma ottenuto solo un errore più criptico.

Edit: Grazie per l'aiuto ragazzi! Ecco una versione di lavoro per chi vuole utilizzare questa funzione:

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";
}
È stato utile?

Soluzione

È necessario typename per dire al compilatore che ::iterator si suppone che sia un tipo. Il compilatore non sa che si tratta di un tipo, perché non sa che cosa è T fino a quando si crea un'istanza del modello. Si potrebbe anche riferirsi a qualche membro di dati statici, per esempio. Questo è il tuo primo errore.

Il secondo errore è che v è un riferimento-to- const . Così, invece di ::iterator è necessario utilizzare ::const_iterator. Non si può chiedere un contenitore costante per un iteratore non const.

Altri suggerimenti

Cambia T::iterator i; a typename T::const_iterator i; perché ::iterator è di tipo T e v è un const &.

Prima di un tipo dipendenti qualificati, è necessario typename. Senza typename, c'è un C ++ parsing regola che dice che i nomi dipendenti qualificati dovrebbero essere analizzati come non-types anche se porta a un errore di sintassi.

typename afferma che il nome che segue deve essere considerato come un tipo. In caso contrario, i nomi vengono interpretati per riferirsi a non-tipi.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top