Typloser std::vector als Parameter
-
Hallo, ich bin noch relativ unerfahren mit C++.
Ich wollte mir mal die Vorteile von templates zu Nutzen machen. Allerdings bin ich dort gleich auf ein Verständnisproblem gestossen. Muss ich zwingend jedem Container bei der Funktionsdefinition einen Typ zuweisen?
void foo(std::vector &vector){} //Fehler void bar(std::vector<int> &vector){}//Funktioniert
Ich würde gerne Algorithmen und Datenstrukturen allgemeiner halten und lieber einen "typlosen" vector übergeben und mich darauf verlassen, dass der Benutzer den Operator == definiert hat.
Sonst müsste ich für floats, ints, longs, chars immer wieder eine neue Funktion definieren. Allerdings glaube ich, dass es einfacher geht.
Das würde ich nun gern von Euch wissen
-
Hallo,
Nimm doch ein Funktionstemplate.
template<typename T> void foo(std::vector<T> &vector){}
Ciao
-
[Edit:]vergiss es, mach was Braunstein sagt[/Edit]
-
Da ein parameter einer 'nomalen' funktin immer nur einen Typ haben kann und es sich bei verschiedenen vectoren ja um verschiedene Typen handelt muss die Funktion auch eine template-funktion sein. z.B.
//für 'beliebige' Container template<typename ContainerType, typename ContentType> void GenericAdd (ContainerType& theContainer, ContentType data) { theContainer.push_back(data); } //für vector template <typename ContentType> void VectorAdd(vector<ContentType> theContainer, ContentType data) { theContainer.push_back(data); } int main(int argc, char* argv[]) { vector<int> vInt; GenericAdd<vector<int>, int> (vInt, 1); VectorAdd<int>(vInt, 2); return 0; }
-
Vielen Dank an alle!
Würde man das mit Methoden innerhalb von Klassen genauso machen?
-
Ja
-
Danke!
Kurze Nachfrage:
//Muss man das so machen? VectorAdd<int>(vInt, 2); //So geht das auch. Wo lieht der Unterschied? VectorAdd(vInt, 2);
Danke!
-
Bei letzterem muß der Compiler nachschaun, ob er rausfinden kann was der Parameter denn sein muß. Hier ist das recht leicht:
Der Parameter des Templates ist vector<T> &, und Du gibst vector<int>& rein. Da sieht er: damit das klappt muß T ein int sein. Und dann benutzt er das auch. Das klappt aber so nicht immer.
Wenn Du z.B. 2 vector<T> übergibst und beim Aufruf übergibst Du einen vector<int> und einen vector<float>, dann wird er sich nicht zwischen den beiden entscheiden können und Du mußt ihm sagen was Du haben willst.MfG Jester
-
Danke!
Ist das normal, dass ich sogar einen Fehler bekomme wenn ich eine Funktionen mit Typ aufrufe die in der selben Datei definiert sind?
Ruft dort z.B. eine Funktion eine andere aus dem selben Header und im selben Namespace auf, dann erhalte ich immer eine Fehlermeldung.
In dem Besipiel oben würde dann zum Beispiel VectorAdd intern GenericAdd aufrufen.
//für 'beliebige' Container template<typename ContainerType, typename ContentType> void GenericAdd (ContainerType& theContainer, ContentType data) { theContainer.push_back(data); } //für vector template <typename ContentType> void VectorAdd(vector<ContentType> theContainer, ContentType data) { GenericAdd<ContentType>(...); //Fehler beim kompilieren GenericAdd(...); //Fehlerfrei }
-
template<typename ContainerType, typename ContentType> void GenericAdd (ContainerType& theContainer, ContentType data)
wie man hier sieht brauch GEnericAdd() 2 template-argumennte.
GenericAdd<ContentType>(...);
und wie man hier sieht, hat GenericAdd() nur ein template-argument. da ist es kein wunder das der compiler meckert.