problem mit templates und iteratoren
-
hab hier ein kleines problem, wahrscheinlich mit der syntax:
1 #include <iostream> 2 #include <vector> 3 4 using namespace std; 5 //template <typename T> 6 7 template<typename T> void showSmallNumbers(const vector<T> &v) 8 { 9 vector<T>::iterator iter; 10 cout << "Iterieren der Liste:" << endl; 11 for(iter = v.begin(); iter != v.end();iter++) 12 { 13 cout << "Iterator: " << *iter << endl; 14 } 15 16 } 17 18 int main (int argc, char** argv) 19 { 20 vector<double> *v = new vector<double>[5]; 21 v->push_back(2.2); 22 v->push_back(2.3); 23 v->push_back(3.4); 24 v->push_back(3.5); 25 v->push_back(3.6); 26 vector<double> d = vector<double>(5); 27 showSmallNumbers(v); 28 return 0; 29 }bei mir gibt das folgende fehlermeldung:
pete@pete-laptop:~/Desktop/cpp$ g++ showsmallnumbers.cpp
showsmallnumbers.cpp: In function »void showSmallNumbers(const std::vector<T, std::allocator<_CharT> >&)«:
showsmallnumbers.cpp:10: Fehler: expected `;' before »iter«
showsmallnumbers.cpp:12: Fehler: »iter« wurde in diesem Gültigkeitsbereich nicht definiert
showsmallnumbers.cpp: In function »int main(int, char**)«:
showsmallnumbers.cpp:28: Fehler: keine passende Funktion für Aufruf von »showSmallNumbers(std::vector<double, std::allocator<double> >*&)«mach ich bei der iteratordeklaration was falsch?!
bzw. warum findet er keine passende funktion dafür?gruss pete
-
petedeluxe2k schrieb:
mach ich bei der iteratordeklaration was falsch?!
Ja, es fehlt ein typename davor.
-
der typ ist doch vector<T> wobei das T als template für z.B double gedacht ist?!
ich versteh das jetzt nicht ganz?!
-
typename std::vector<T>::iterator MyIter;Du musst dem Compiler mitteilen, dass
iteratorein Typ ist, da dies bei Templates nicht immer genau gesagt werden kann.Grüssli
-
ok danke... damit ist das problem des iterators schon mal beseitigt

warum findet er nun keine passende methode?pete@pete-laptop:~/Desktop/cpp$ g++ showsmallnumbers.cpp
showsmallnumbers.cpp: In function »int main(int, char**)«:
showsmallnumbers.cpp:27: Fehler: keine passende Funktion für Aufruf von »showSmallNumbers(std::vector<double, std::allocator<double> >*&)«
-
Weil die Schnittstelle nicht zu der Übergabe in main() passt: Du erzeugst 'nen Vektor auf dem Heap, den du dann showSmallNumbers() übergibst, die allerdings ne Referenz auf 'nen konstanten Vektor erwartet.
-
petedeluxe2k schrieb:
vector<double> *v = new vector<double>[5];Die eckige Klammer sollte wohl zu einer runden Klammer werden

-
ok danke. hab in die signatur nur folgendes geschrieben
(vector<T> *v) damit passt es vom funktionsaufruf.versteh ich das richtig, dass mit der übergabe einer konstanten referenz auf ein objekt, wie z.B. mit (const vector<T> &v) einfach ein schon bestehendes objekt übergebe?!
wenn ich an einen kopierkonstruktor denk, übergeb ich ja auch eine const objekttyp &o. also ein bestehende objekt.in dem fall müsste ich ein objekt der klasse, welches durch den konstruktor auf dem stack erzeugt wird, übergeben?!
also z.B.
vector<double> d = vector<double>(5);würde das gehen?
und warum muss das ganze, wie bei einem kopierkonstruktor const sein?
danke schon mal

-
Erst einmal: Den Vektor kannst du entweder auf dem Stack der main()-Funktion oder auf dem Heap der Anwendung erstellen.
Das Anlegen auf dem Stack funktioniert nach dem Prinzip "Typ variablenname" (also bspw. "int x"). Wenn du dich für den Heap entscheidest, musst du den new-Operator verwenden, der einen Zeiger auf das neu erstellte Objekt zurückgibt.Je nachdem, welchen Weg du oben gewählt hast, musst du jetzt deine Parameterliste und den Funktionskörper deiner Funktion anpassen.
Falls du den Vektor auf dem Stack angelegt hast, kannst du das Argument an die Funktion jetzt entweder durch eine Kopie oder eben durch eine Referenz übergeben. Eine Referenz ist nichts anderes als ein Alias-Name für das übergeben Objekt innerhalb der Funktion. Mit "const" kannst du einen zusätzlichen Qualifizierer setzen, der festlegt, dass es sich um ein unveränderliches Objekt handelt.
Möglichkeit 2: Du hast dich für die Erzeugung auf dem Heap entschieden, musst deiner Funktion also einen Zeiger auf das erstellte Objekt übergeben. Im Funktionskörper musst du jetzt auch die Zugriffe zeigertypisch anpassen.Die Vorteile von Referenzen gegenüber Zeigern sollten eigentlich bekannt sein, einen will ich aber doch noch erwähnen: Mit einer Referenz auf ein konstantes Objekt hast du keine unnütze Kopie für die Funktion angefertigt, musst dich andererseits aber auch nicht mit der Zeigersyntax herumschlagen.
So, HTH

-
petedeluxe2k schrieb:
versteh ich das richtig, dass mit der übergabe einer konstanten referenz auf ein objekt, wie z.B. mit (const vector<T> &v) einfach ein schon bestehendes objekt übergebe?!
Ja. Die Übergabe per Referenz kopiert das Objekt generell nicht, sondern übergibt es sozusagen direkt. Wenn du die Referenz konstant übergibst, kann das referenzierte Objekt von der Funktion nicht verändert werden. Was du dabei beachten musst: Bei konstanten Referenzen kann man nicht nur Variablen übergeben, in so einem Fall wird dann eine temporäre Kopie erstellt.
Also:
void ReferenceFunction(std::string& Str); void ConstRefFunction(const std::string& Str); int main() { ReferenceFunction("Hallo"); // geht nicht, Referenz muss an Objekt gebunden sein ConstRefFunction("Hallo"); // geht, temporäre Kopie wird erstellt. }Somit ist es für konstante Referenzen auch möglich, Defaultparameter anzugeben.