STL-Iteratoren casten
-
Badestrand schrieb:
SomeClass* sc = new SomeClass(); DoSomething( sc );Wie kann man sowas lösen?
class SomeClass {}; void DoSomething( const SomeClass* elem ) {} ... vector<SomeClass> vec; for ( vector<SomeClass>::iterator iter=vec.begin(); iter!=vec.end(); ++iter ) // ++iter DoSomething( *iter );
-
Ne, eben nicht

Wenn man den Iterator dereferenziert, kommt ein vector<..>::value_type bei raus.Und ob iter++ oder ++iter ist in der for-Schleife egal :p
-
überladen?
-
Checker&Murckser schrieb:
überladen?
Ja gut, das geht schon, aber dann hätte ich den Code doppelt
Ist zwar eine Lösung, aber designtechnisch auch nur halb gebacken..Oh, Juchu, ich habs!! Hab gemerkt, dass push_back auch einen dereferenzierten Iterator als "const Typ&" annimmt

Also:
void DoSomething( const SomeClass& elem ) {} vector<SomeClass> vec; for ( vector<SomeClass>::iterator iter=vec.begin(); iter!=vec.end(); iter++ ) DoSomething( *iter ); SomeClass cl; DoSomething( cl );Freude

-
++iterBei Iteratoren ++iter ! Merk dir das...

-
camper schrieb:
vector: ja; string: nein (auch wenn es wohl keine bestehende Implementation kaputtmachte, wenn man das auch für string festlegte).
das wurde doch 2003 so festgelegt, oder?
-
Der Grund:
==iter inkrementiert erst und liefert dann den erhaltenen Wert zurueck, iter++ speichert den Wert, inkrementiert dann und liefert am ende den gespeicherten Wert - sprich es muss eine Kopie angelegt werden, was sowohl speicher als auch Zeit kostet. (Gilt im Endeffekt fuer alle ueberladenen inkrement-operatoren, nur bei Standardtypen wie int ist der compiler (meist) schlau genug, keinen overhead zu produzieren.
-
Hm, war mir neu, leuchtet aber ein

Aber seid ihr euch sicher, dass er den Wert speichert und zurückgibt, obwohl er gar nicht gebraucht/abgefragt wird?
-
In dem Moment, wo der op++ aufgerufen wird, ist noch gar nicht klar, ob der Rückgabewert weiterverwendet werden soll - also bleibt dem Operator gar nichts anderes übrig als ihn zu kopieren (die eigene Position wird als Nebeneffekt geändert, also stimmt sie nicht mehr mit dem überein, was der Aufrufer erwartet). Wenn du den Rückgabewert nicht nutzt, darf (
nicht 'muss') der Compiler die ganze Kopiererei natürlich wegoptimieren - aber verlassen würde ich mich nicht darauf.PS: Und der typische Aufbau der Inkrement-Operatoren sieht so aus:
iter& iter::operator++() { //bewege *this vorwärts return *this; } iter iter::operator++(int) { iter tmp=*this; ++*this; return tmp; }
-
otze schrieb:
camper schrieb:
vector: ja; string: nein (auch wenn es wohl keine bestehende Implementation kaputtmachte, wenn man das auch für string festlegte).
das wurde doch 2003 so festgelegt, oder?
Für vector steht es explicit da 23.2.4/1
The elements of a vector are stored contiguously, meaning that if v is a vector<T, Allocator> where T is some type other than bool, then it obeys the identity &v[n] == &v[0] + n for all 0 <= n < v.size().
Für basic_string existiert keine solche Passage an entsprechender Stelle.