Frage

Ich versuche, eine Funktion zu schreiben, eine Darstellung von gemeinsamen STL-Containern drucken (Vektor, Liste, etc ..). Ich gab die Funktion einen Template-Parameter T, das, zum Beispiel, könnte Vektor darstellen. Ich habe Probleme einen Iterator vom Typ T zu bekommen.

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

Ich habe versucht, ‚Typnamen T :: Iterator‘, wie der Compiler vorgeschlagen, bekam aber nur einen kryptischen Fehler.

Edit: Vielen Dank für die Hilfe Jungs! Hier ist eine funktionierende Version für jeden, der diese Funktion nutzen:

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";
}
War es hilfreich?

Lösung

Sie müssen typename den Compiler sagen, dass ::iterator soll ein Typ sein. Der Compiler weiß nicht, dass es eine Art ist, weil es nicht weiß, was T ist, bis Sie die Vorlage instanziiert. Es könnte auch zu einem gewissen statischen Datenelement, zum Beispiel beziehen. Das ist Ihr erster Fehler.

Ihr zweiter Fehler ist, dass v ist eine Referenz-to const . Anstatt also ::iterator Sie haben ::const_iterator zu verwenden. Sie können nicht einen konstanten Behälter für einen nicht-const iterator fragen.

Andere Tipps

Ändern T::iterator i; zu typename T::const_iterator i; weil ::iterator ist vom Typ T und v ist ein const &.

Vor einem qualifizierten abhängigen Typ, benötigen Sie typename. Ohne typename gibt es eine C ++ Regel Parsen, die besagen, dass qualifizierter abhängiger Name als non-types analysiert werden soll, selbst wenn es zu einem Syntaxfehler führt.

typename besagt, dass der Name, der als eine Art folgt behandelt werden soll. Andernfalls werden interpretiert Namen zu Nicht-Typ beziehen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top