Template mit String-Array besetzen
-
Ich habe Probleme bei folgender Klasse (gekürzt auf Problemfeld) und deren Benutzung:
counterpart.htemplate <class T> class Counterpart { public: Counterpart(T *object, unsigned size_tmp); private: T *object; const unsigned size; unsigned count; };counterpart.cpp
template<class T> Counterpart<T>::Counterpart( T *object, unsigned size_tmp) : size(size_tmp) { this.object = object; count = 0; }Hier ist der Teil in der der Code zur Anwendung kommt:
irgendwas.cpp
Counterpart<string *> counterpart_az ( new string[9] { string("bliblablub"), string("bliblablub"), string("bliblablub"), string("bliblablub"), string("bliblablub"), string("bliblablub"), string("bliblablub"), string("bliblablub"), string("bliblablub") }, 9 );Wenn ich das jetzt compiliere, bekomme ich folgende Fehler-Meldung vom Compiler
../scan_site.cpp:29:1: Fehler: keine passende Funktion für Aufruf von »Counterpart<std::basic_string<char>*>::Counterpart(std::string*, int)« ../scan_site.cpp:29:1: Anmerkung: Kandidaten sind: ../counterpart.h:14:2: Anmerkung: Counterpart<T>::Counterpart(T*, unsigned int) [with T = std::basic_string<char>*] ../counterpart.h:14:2: Anmerkung: keine bekannte Umwandlung für Argument 1 von »std::string* {aka std::basic_string<char>*}« nach »std::basic_string<char>**« ../counterpart.h:12:7: Anmerkung: Counterpart<std::basic_string<char>*>::Counterpart(const Counterpart<std::basic_string<char>*>&) ../counterpart.h:12:7: Anmerkung: Kandidat erwartet 1 Argument, 2 angegeben ../scan_site.cpp: In Funktion »void scan_zdf(MYSQL*)«: ../scan_site.cpp:137:28: Warnung: extended initializer lists only available with -std=c++0x or -std=gnu++0x [standardmäßig aktiviert]Wo liegt das Problem?
-
Der Konstruktor von Counterpart<T> erwartet einen Zeiger auf T - wenn du als Template-Parameter einen Pointer (string*) verwendest, benötigst du dort einen Zeiger auf Zeiger (also string**).
(Was soll eigentlich der Sinn der Konstruktion sein? Und was spricht gegen std::vector<> und Kollegen?)
-
Counterpart(T *object, unsigned size_tmp);
Setz da doch für T mal deinen Typen ein (string*). Welchen Typ hat dann object, und was übergibst du.
Übrigens steht das auch da in der Fehlermeldung. Die sehen zwar oft schlimm aus, aber man kann sie tatsächlich lesen.
-
Gibt nicht new einen Zeiger auf den von ihm reservierten Speicherbereich zurück und das string[9] Objekt ist praktisch das Template <string *>.
Wegen der Frage von CStoll, ich durchsuche mit meinem Programm eine Webseite und und füttere damit eine Datenbank. Da das Programm mit Threads arbeiten soll muss der main-thread sowie die zusätzlichen Threads solbald sie nichts mehr zu tun haben, also die html-seite heruntergeladen durchsucht und das Ergebnis in einer Datenbank gespeichert hat die nächste Url anfordern. Da der Main-Thread auch mit dem durchsuchen beschäftigt ist erstelle ich ein globales Objekt bei dem die Threads schauen können ob noch eine Url verfügbar ist und wenn ja eine anfordern können.
template <class T> class Counterpart { public: Counterpart(T *object, unsigned size_tmp); T *get_object(); bool check_for_object() { return count <= size; } virtual ~Counterpart(); private: T *object; const unsigned size; unsigned count; };Das Programm muss je nachdem in welchen Arbeitsschritt das Programm ist, bestimmte html-seiten von der Website durchsuchen, und brauch für die Datenbank eine Unterschiedliche Anzahl von Zusatzinformationen daher das Template.
-
tupolew schrieb:
Gibt nicht new einen Zeiger auf den von ihm reservierten Speicherbereich zurück und das string[9] Objekt ist praktisch das Template <string *>.
Ja, new[] liefert einen Zeiger auf std::tring - dein Konstruktor benötigt aber einen Zeiger auf einen Zeiger.
PS: Und das Anwendungsszenario kann imho problemlos mit STL-Containern gelöst werden, auf den ersten Blick würde ich eine std::queue<> verwenden (eventuell mit einem Wrapper darum, der sich um die Thread-Sicherheit kümmert).
Edit: Nur ein kleiner Tip: Wenn du in deinem Nutzerprofil die Option "BBCode immer aktivieren" einschaltest, sieht man auch deine Code-Formatierungen

-
tupolew schrieb:
Wo liegt das Problem?
Dein Templateparameter ist falsch.
Sollte sicherCounterpart<string> counterpart_az ( new string[9] { string("bliblablub"), string("bliblablub"), string("bliblablub"), string("bliblablub"), string("bliblablub"), string("bliblablub"), string("bliblablub"), string("bliblablub"), string("bliblablub") }, 9 );heißen.
-
Danke für den Tipp mit std::queue, die Klasse werde ich verwenden. Aber da man aus Fehlern lernen soll, möchte ich den Fehler in meiner Klasse beheben. Ursprünglich hatte ich in der Klassendeklaration folgenden Quellcode:
template <class T> class Counterpart { public: Counterpart(T object_tmp, unsigned size_tmp); T *get_object(); bool check_for_object() { return count <= size; } virtual ~Counterpart(); private: T *object; const unsigned size; unsigned count; };Aber dann kam folgende Fehlermeldung die mich ziemlich verwirrt hat und dann irgendwann der Scheiß mit den doppelten Pointer rauskahm.
g++ -L/usr/lib/mysql -o "netzwerk" ./counterpart.o ./database.o ./main.o ./scan_site.o -lmysqlclient -lboost_regex -lcurl ./scan_site.o: In function `__static_initialization_and_destruction_0': /home/tupolew/workspace/netzwerk/Debug/../scan_site.cpp:17: undefined reference to `Counterpart<std::basic_string<char, std::char_traits<char>, std::allocator<char> >*>::Counterpart(std::basic_string<char, std::char_traits<char>, std::allocator<char> >*, unsigned int)' /home/tupolew/workspace/netzwerk/Debug/../scan_site.cpp:17: undefined reference to `Counterpart<std::basic_string<char, std::char_traits<char>, std::allocator<char> >*>::~Counterpart()' collect2: ld gab 1 als Ende-Status zurück
-
Hallo,
Templates müssen komplett im Header definiert sein, s. auch FAQ-Beitrag http://www.c-plusplus.net/forum/viewtopic-var-t-is-39467.html
-
Danke