compilerfehler bei iteratorenvergleich
-
hola leute
folgendes scenario:
volumes<char> vol; volumes<char>::iterator iter(vol), end; while(iter != end) { std::cout << *iter++ << std::endl; }hier gibt es kein problem. wenn ich aber folgendes schreibe:
volumes<char>::iterator iter(volumes<char>()), end; while(iter != end) // (22) { std::cout << *iter++ << std::endl; }bekomm ich in zeile (22) folgende fehlermeldung:
1>main.cpp(22): error C2678: Binärer Operator '!=': Es konnte kein Operator gefunden werden, der einen linksseitigen Operanden vom Typ 'overloaded-function' akzeptiert (oder keine geeignete Konvertierung möglich) 1> C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\exception(522): kann 'bool std::operator !=(const std::exception_ptr &,const std::exception_ptr &)' sein [bei der Verwendung der argumentbezogenen Suche gefunden] 1> C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\exception(527): oder "bool std::operator !=(std::nullptr_t,const std::exception_ptr &)" [bei argumentbezogenem Lookup gefunden] 1> C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\exception(532): oder "bool std::operator !=(const std::exception_ptr &,std::nullptr_t)" [bei argumentbezogenem Lookup gefunden] 1> C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\system_error(443): oder "bool std::operator !=(const std::error_code &,const std::error_condition &) throw()" [bei argumentbezogenem Lookup gefunden] 1> C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\system_error(450): oder "bool std::operator !=(const std::error_condition &,const std::error_code &) throw()" [bei argumentbezogenem Lookup gefunden] 1> C:\Program Files (x86)\Windows Kits\8.0\Include\shared\guiddef.h(197): oder "bool operator !=(const GUID &,const GUID &)" 1> bei Anpassung der Argumentliste '(overloaded-function, txl::win::volume_iterator<CHAR>)' 1> with 1> [ 1> CHAR=char 1> ] 1>main.cpp(22): fatal error C1903: Weiterverarbeitung nach vorherigem Fehler nicht möglich; Kompilierung wird abgebrochen. 1> 1>Fehler beim Buildvorgang.die volumes-klasse mit dem iterator sieht folgend aus:
template<class CHAR> class volumes; template<class CHAR> class volume_iterator : public std::iterator<std::input_iterator_tag, std::basic_string<CHAR> > { public: typedef CHAR char_type; template<class> friend class volumes; volume_iterator(const volumes<char_type> &v) { v(*this); } volume_iterator(void) { } ~volume_iterator(void) { if(m_handle != txl::win::handle()) ::FindVolumeClose(m_handle.native_handle()); } std::basic_string<char_type>& operator*(void) { return m_str; } volume_iterator& operator++(void) { char_type buffer[MAX_PATH]; if(find_next_volume(buffer, MAX_PATH) == 0) { m_str.clear(); ::FindVolumeClose(m_handle.native_handle()); m_handle = txl::win::handle(0); } else { m_str = buffer; } return *this; } volume_iterator operator++(int) { volume_iterator temp; temp.m_str = m_str; char_type buffer[MAX_PATH]; if(find_next_volume(buffer, MAX_PATH) == 0) { m_str.clear(); ::FindVolumeClose(m_handle.native_handle()); m_handle = txl::win::handle(0); } else { m_str = buffer; } return temp; } bool operator==(const volume_iterator &it) const { return m_handle == it.m_handle; } bool operator!=(const volume_iterator &it) const { return m_handle != it.m_handle; } private: txl::win::handle m_handle; std::basic_string<char_type> m_str; BOOL find_next_volume(char *buffer, DWORD size) { return ::FindNextVolumeA(m_handle.native_handle(), buffer, size); } BOOL find_next_value(wchar_t *buffer, DWORD size) { return ::FindNextVolumeW(m_handle.native_handle(), buffer, size); } }; /* class volume_iterator */ template<class CHAR> class volumes { public: typedef CHAR char_type; typedef volume_iterator<char_type> iterator; void operator()(volume_iterator<char_type> &iter) const { char_type buffer[MAX_PATH]; iter.m_handle = find_first_volume(buffer, MAX_PATH); iter.m_str = buffer; } private: txl::win::handle find_first_volume(char *buffer, DWORD size) const { return ::FindFirstVolumeA(buffer, size); } txl::win::handle find_first_volume(wchar_t *buffer, DWORD size) const { return ::FindFirstVolumeW(buffer, size); } }; /* class volumes */wo liegt hier der fehler ?
Meep Meep
-
Edit: Das ist kein Bug! Mir fällt gerade auf, das was du hast ist eine Funktionsdeklaration!
Guck mal genau hin :xmas1:
-
volumes<char>::iterator iter(volumes<char>())Das deklariert eine lokale Funktion,
- die einen Funktionszeiger auf eine Funktion nimmt, die keine Parameter nimmt und
volumes<char>zurückgibt, - und einen
volumes<char>::iteratorzurückgibt.
Dieses Problem tritt mit direct-initialization in Form von geschweiften Klammern nicht auf.
Wenn du also C++11 Unterstützung hast, nimmvolumes<char>::iterator iter{volumes<char>{}}Und gewöhn' dir an, ab sofort alle Konstruktoren mit geschweiften Klammern aufzurufen.
- die einen Funktionszeiger auf eine Funktion nimmt, die keine Parameter nimmt und
-
Die Lösung ohne uniform-initialization sind im Übrigen Klammern:
volumes<char>::iterator iter((volumes<char>()));
-
hallo leute, danke erstmals fuer die hilfe.
hab hier VC2012 installiert und hab es mal so probiert:
volumes<char>::iterator iter{volumes<char>{}}, end;nun bekomm ich
1>main.cpp(20): error C2601: 'iter': Lokale Funktionsdefinitionen sind unzulässigheisst das das vc2012 noch keine unterstuetzung fuer C++11 hat ? also was die initialisierungslisten betrifft ?
mir ist auch neu das man eine funktion auch mit geschweiften klammern definieren kann.volumes<char>::iterator iter((volumes<char>())), end;das ist die einzige variante die der compiler schluckt wenn ich ein temporaeres objekt verwenden will. wobei mir die doppelte klammer ueberhaupt nicht gefaellt und ich auch nicht wirklich weiß, warum es nun keine funktionsdeklaration ist.
Meep Meep
-
ich auch nicht wirklich weiß, warum es nun keine funktionsdeklaration ist.
Nun kann der Compiler nicht mehr annehmen, dass es eine Funktionsdeklaration ist, weil innen keine Parameterliste mehr steht sondern ein Ausdruck.
-
Meep Meep schrieb:
hallo leute, danke erstmals fuer die hilfe.
hab hier VC2012 installiert und hab es mal so probiert:
volumes<char>::iterator iter{volumes<char>{}}, end;nun bekomm ich
1>main.cpp(20): error C2601: 'iter': Lokale Funktionsdefinitionen sind unzulässigheisst das das vc2012 noch keine unterstuetzung fuer C++11 hat ? also was die initialisierungslisten betrifft ?
mir ist auch neu das man eine funktion auch mit geschweiften klammern definieren kann.*Facepalm*
Nein, das soll ja gerade verhindern dass es als Funktionsdeklaration interpretiert wird!Und die Fehlermeldung besagt ganz klar, dass VC++-2012 noch nicht genügend C++11-Unterstützung hat, weil das gültiges C++11 ist; Du musst wohl leider vorerst cooky's Variante nutzen.
-
Stichwort: Most Vexing Parse. Die wohl duemmste Erfindung, die ich je in einer Programmiersprache gesehen habe.