Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » return iterator

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
05.08.2009, 16:01 Uhr
Lensflare



Hallo.

ich bekomme beim Versuch einen iterator zurückzugeben bei folgendem code eine Fehlermeldung:


C++:
#ifndef LTEST_H
#define LTEST_H

#include <list>

template<typename T>
class LinkedListWrapper {

protected:

    std::list<T> wrappedList;

public:

    std::list<T>::iterator IteratorBegin() const {
        return wrappedList.begin();
    }

    //...
};

#endif //LTEST_H




Code:
1>c:\dev\c++\vs\containers\Test.h(15) : warning C4346: 'std::list<T>::iterator': Abhängiger Name ist kein Typ
1>        Präfix mit 'typename' zum Angeben eines Typs
1>        c:\dev\c++\vs\containers\Test.h(20): Siehe Verweis auf die Instanziierung der gerade kompilierten Klassen-template "LinkedListWrapper<T>".
1>c:\dev\c++\vs\containers\Test.h(15) : error C2146: Syntaxfehler: Fehlendes ';' vor Bezeichner 'IteratorBegin'
1>c:\dev\c++\vs\containers\Test.h(15) : error C4430: Fehlender Typspezifizierer - int wird angenommen. Hinweis: "default-int" wird von C++ nicht unterstützt.
1>c:\dev\c++\vs\containers\Test.h(17) : warning C4183: 'IteratorBegin': Rückgabetyp fehlt; Memberfunktion, die 'int' zurückgibt wird angenommen



Könnt ihr mir sagen wo der Fehler liegt?

Wenn ich den iterator als Typ für eine lokale Variable nehme, dann geht es.
Deswegen ist diese Fehlermeldung für mich völlig unverständlich.
--
Wenn das Gehirn so einfach wäre, dass wir es verstehen könnten, wären wir so einfach, dass wir es nicht verstehen könnten.
(Emerson Pugh Trost)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
05.08.2009, 16:15 Uhr
Tommix



Hallo,

C++:
typename std::list<T>::iterator IteratorBegin() const {
...


- Tommix
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
05.08.2009, 17:03 Uhr
Lensflare



Ok, danke schon mal.

Ich hab mich mal über typename schlau gemacht...
http://pages.cs.wisc.edu/~driscoll/typename.html

Anscheinend ist typedef bei qualifizierten, abhängigen namen nötig, weil es sonst sowohl als Typ als auch als statische Variable verstanden werden könnte.

So weit kann ich das nachvollziehen.

Dem Artikel habe ich auch entnommen, dass der Compiler keine kontextbezogenen Entscheidungen macht. Ich muss typename immer explizit angeben (oder weglassen).

Aber trotzdem kompiliert bei mir der folgende Code ohne Fehler und macht auch das, was er machen soll:


C++:
    bool Contains(const T &e) const {
        std::list<T>::const_iterator it = wrappedList.begin();
        while(it != wrappedList.end()) {
            if(*it == e) {
                return true;
            }
            ++it;
        }
        return false;
    }



Müsste ich da nicht auch typename benutzen?
Liegt es vielleicht am MS-Compiler? (Visual C++ 2008 Express Edition)
--
Wenn das Gehirn so einfach wäre, dass wir es verstehen könnten, wären wir so einfach, dass wir es nicht verstehen könnten.
(Emerson Pugh Trost)

Dieser Post wurde am 05.08.2009 um 17:04 Uhr von Lensflare editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
05.08.2009, 21:36 Uhr
0xdeadbeef
Gott
(Operator)


Ja, da solltest du auch typename benutzen müssen, und ja, das wird wohl am Compiler liegen.

typename musst und darfst du allerdings in der Form nur innerhalb von Vorlagen für Typen benutzen, die innerhalb von Template-Parametern abhängigen Typen definiert werden. Also:

C++:
template<typename T> void foo() {
  typename T::type bar;
  typename std::list<T>::iterator baz;
  // aber:
  std::list<int>::iterator i;
}


Der Hintergrund dabei ist, dass etwas in der Art denkbar wäre:

C++:
struct A { typedef int foo; };
struct B { static int foo; };

template<typename T> void bar() {
  typename T::foo baz;
}

// ...

bar<A>(); // ok
bar<B>(); // Ups.


in ähnlicher Weise könnten über Spezialisierungen Sonderfälle in Klassenvorlagen auftreten, in denen ein Bezeichner, der normalerweise ein Typ wäre, irgendetwas anderes ist.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: