eigener find-Algorithmus als Template...
-
Hi,
was an der Definition mache ich falsch?
Und wann muss ich beim Aufruf mit angeben, um welchen Typ es sich handelt und wann nicht?#include <iostream> #include <list> #include <cassert> using namespace std; template <typename T> bool myfind(list<T>::iterator beg, list<T>::iterator end, T const &val) { for( ; beg != end; ++beg) if(*beg == val) return true; return false; } int main() { list<int> ilist; for(int i(0); i <= 10; ++i) ilist.push_back(i*10); assert(myfind(ilist.begin(), ilist.end(), 50)); //assert(!::myfind(ilist.begin(), ilist.end(), 110)); return 0; }Meldung:
9.12.cpp:9: Fehler: Templatedeklaration von »bool myfind«
9.12.cpp:9: Fehler: expected)' before »beg« 9.12.cpp:9: Fehler: expected)' before »end«
9.12.cpp:9: Fehler: expected primary-expression before »const«
9.12.cpp: In function »int main()«:
9.12.cpp:25: Fehler: »myfind« wurde in diesem Gültigkeitsbereich nicht definiertDanke schonmal.
-
Ok ich habs! Was so ein paar typenames in Verbindung mit Iteratoren bewirken können. Auch wenn ich die Notwendigkeit immer noch nicht ganz gecheckt habe...
-
Probiers mal mit:
bool myfind(T beg, T end, T const &val){...}
-
Salut,
davon abgesehen, dass es mit den typenames vor den iterator-defs jetzt funktioniert, kann es stimmen, dass T gleichzeitig für den Typ (zB int) steht und dann auch noch für einen iterator<int>?
-
Also das typedef ist dazu da, um dem Compiler zu sagen, dass das kommende eine Typdefinition ist.
davon abgesehen, dass es mit den typenames vor den iterator-defs jetzt funktioniert, kann es stimmen, dass T gleichzeitig für den Typ (zB int) steht und dann auch noch für einen iterator<int>?
Naja. Überleg dir mal, wenn du in einem std::vector suchen willst, oder auch in einem normalen Array. Dafür müsstest du jedesmal verschiedene Funktionen schreiben, ohne, dass sich der Algorithmus verändern würde.
Die Standardbibliothek macht das genau so.
Du kannst auch 2 Integer angeben, aber das wären schlichtweg unsinnige Parameter.http://www.cplusplus.com/reference/algorithm/find.html
Da siehst du, dass das der normale Weg ist. Wenn der Programmierer einfach nicht viel dabei überlegt, dann ist er selber schuld, respektive es kompiliert nicht, wenn kein Operator * definiert ist.
-
Also das typedef ist dazu da, um dem Compiler zu sagen, dass das kommende eine Typdefinition ist.
Ich habs bisher nur in Verbindung Templates->Iteratoren gesehen und benutzt.
Was sagt denn "list<T>::iterator beg" ohne ein davorgestelltes typename aus?Das es generischer geht, als von mir geschrieben weiss ich. War nur als kleine Übung gedacht und dafür benötige ich jetzt keinen vector, deque, whatever.
Und da du die Reference schon ansprichst, dort wird nicht für beide Typen der gleiche typename/class -Name benutzt, sondern einmal T und einmal Iterator.
Und das war es ja, was mich an deinem Code verwundert hat!
-
Jetzt versteh ich was du meinst. Es ist also erlaubt nur einen typename/class-Parameter, zb. T einzuführen und mit diesem überall zu arbeiten, wo etwas ersetzt werden kann, egal um was es sich handelt. Aber es muss natürlich die richtige Reihenfolge beim Aufruf beibehalten werden.
-
this!=that schrieb:
Jetzt versteh ich was du meinst. Es ist also erlaubt nur einen typename/class-Parameter, zb. T einzuführen und mit diesem überall zu arbeiten, wo etwas ersetzt werden kann, egal um was es sich handelt. Aber es muss natürlich die richtige Reihenfolge beim Aufruf beibehalten werden.
Ein Template-Parameter hat immer genau einen Typ. Die verwenden dort zwei verschiedene Template-Parameter und überlassen dem Compiler die Arbeit Anhand der Parameter der Template-Funktion die Template-Parameter herauszufinden.
In deinem Fall brauchst du das typename davor, da der Compiler sonst annimmt, dass es sich bei iterator um eine Variable und nicht um einen Typ handelt. Wobei ich eigentlich glaube, dass er das innerhalb der Parameterliste nicht tut, aber anders kann ich mir deinen Fehler gerade nicht erklären.
-
template<typename Iter, typename T> bool myfind(Iter const &begin, Iter const &end, T const &val);