String über const-Iteratoren-Bereich konstruieren
-
Hallo,
ich möchte einen String über einen Bereich konstruieren, also den Konstruktor 'basic_string(IT start, IT end)' verwenden. Dabei ist einer der Iteratoren allerdings konstant.
Folgender Code
#include <string> int main() { std::string a("Hallo"); std::string::const_iterator ax = a.end(); std::string b(a.begin(), ax); }funktioniert im MSVC++ 2005 zwar. Im GCC hingegen erhalte ich folgende Fehlermeldung:
main.cpp:7: error: no matching function for call to `basic_string::basic_string(__gnu_cxx::__normal_iterator<char*, basic_string>, __gnu_cxx::__normal_iterator<const char*, basic_string>&)'
C:/Programme/.../basic_string.tcc:235: note: candidates are: [Auflistung aller möglichen Konstruktoren, nur nicht dessen über einen Bereich]Scheinbar ist in den GCC-Headern ein 'basic_string::const_iterator' als Iterator über 'const char*' definiert und der Compiler kann diesen Typ nicht in einen Iterator über 'char*' konvertieren -- oder umgekehrt.
Ist das legales C++? Ist demnach mein Code falsch? Oder ist das Verhalten undefiniert und es ist reine Glückssache, ob mein Code läuft?
Und: Was ist, rein von der Logik, an dem Code auszusetzen? Wäre es nicht sinnvoller, den 'const_iterator' so zu definieren, dass mein Code funktioniert?
Ich hätte erwartet, dass (weil die beiden Parameter ja verschiedenen Typs sind) der Compiler den ersten Parameter implizit nach 'const' castet und als Templatetypen für den Konstruktoraufruf dann IT = 'basic_string::const_iterator' verwendet.EDIT: Mir fällt gerade auf, wie besch...eiden der Titel gewählt ist. Sorry.
-
das ist ein normales verhalten
das liegt an den templates
template<class T> void foo(T a,T b); char* a; const char* b; foo(a,b);der compiler schaut sich das erste argument an, und schließt daraus(vereinfacht ausgedrückt) T. in deinem fall char*.
nun sieht er den nächsten Parameter, und dort muss der typ nach T konvertierbar sein(das der compiler nicht genauer hinschaut, liegt an den unheimlich komplexen überladungsregeln, die ich noch nicht richtig durchschaut hab^^) in c++ sind aber konstante werte nicht zu nicht konstanten konvertierbar->fehler. Das ist auch gut so, denn darauf basiert die const-correctness.laut standard muss jeder iterator in einen const_iterator umwandelbar sein, darauf kannst du dich also zumindest verlassen.
//für zeiger foo(const_cast<const char*>(a),b);//für alle iteratoren typedef /*deinContainer*/ Container; typedef Container::const_iterator const_iterator; foo(const_iterator(a),b);
-
otze schrieb:
foo(const_iterator(a),b);Danke. Ich hätte irgendwie erwartet, dass sich der Compiler zur Bestimmung des Typenparametertyps (...) nicht nur den ersten Parameter anschaut und obiges daher automatisch macht. Schade.