Templatefunktion wird nicht gefunden
-
Ich habe einen Sourcecode in Java, den ich nach C++ umschreibe.
Der alte Code arbeitet viel mit der Klasse java.lang.String.
Um moeglichst wenig Aenderungen daran vorzunehmen habe ich eine Klasse String von std::string abgeleitet und ihr die noetigen Methoden geschrieben, so dass ich am alten Code desbzgl. keine Aenderungen vornehmen musste(Prinzip: "old code calls new code"), unter anderem die Methoden startsWith(...) und endsWith(...).
http://java.sun.com/j2se/1.3/docs/api/java/lang/String.html
Da beide Methoden recht aehnlich sind, habe ich die Core-Funktionalitaet in eine separate Template Funktion verbannt, die dann nur noch mit den entsprechenden Parametern aufgerufen wird.bool String::startsWith(const String& prefix) const { return startsEndsWith<const_iterator, prefix.begin(), this->begin()>(prefix); } bool String::endsWith(const String& suffix) const { return startsEndsWith<const_reverse_iterator, suffix.rbegin(), this->rbegin()>(suffix); }Die Template Funktion ist eine Abstraktion der beiden *With(...) Methoden und sieht wie folgt aus:
template<typename iterator, iterator thisOffset, iterator argOffset> bool String::startsEndsWith(const String& presuffix) const { int i=presuffix.length(); iterator it(thisOffset), it0(argOffset); while(*it++ == *it0++ && i--); if(i==0) return true; return false; }Leider ist noch irgendwo der Wurm drin, denn der Compiler meint:
compiling aiplayer.cpp (g++) ./string.hpp: In member function 'bool String::endsWith(const String&) const': ./string.hpp:64: error: 'suffix' cannot appear in a constant-expression ./string.hpp:64: error: `.' cannot appear in a constant-expression ./string.hpp:64: error: a function call cannot appear in a constant-expression ./string.hpp:64: error: `this' cannot appear in a constant-expression ./string.hpp:64: error: '->' cannot appear in a constant-expression ./string.hpp:64: error: a function call cannot appear in a constant-expression ./string.hpp:64: error: no matching function for call to 'String::startsEndsWith(const String&) const'Anscheinend findet er meine Template Funktion gar nicht, obwohl die Klasse String und String::startsWith(...) und String::endsWith(...), sowieString::startsEndsWith(...) alle in einem Sourcefile, naemlich "string.hpp" sind.
Schonmal Danke im Voraus und sorry, falls der "Fehler" offensichtlich ist - bin atm ein bisschen aus der Uebung.
-
Templateparameter müssen compiletime-konstant sein, da Templates, anders als Generics, vollständig zur Compiletime aufgelöst werden, suffix als Parameter einer zur Laufzeit aufgerufenen Funktion ist das logischerweise nicht.
Du darfst nur den Iterator-Typ in die Template-Argumentliste packen, die übergebenen Iteratoren müssen in die normale Argumentliste.
-
LordJaxom schrieb:
Templateparameter müssen compiletime-konstant sein, da Templates, anders als Generics, vollständig zur Compiletime aufgelöst werden, suffix als Parameter einer zur Laufzeit aufgerufenen Funktion ist das logischerweise nicht.
Du darfst nur den Iterator-Typ in die Template-Argumentliste packen, die übergebenen Iteratoren müssen in die normale Argumentliste.
Aber die beiden uebergebenen Iteratoren sind doch konstant -->
const_iterator begin() const;
-
Raptor schrieb:
Aber die beiden uebergebenen Iteratoren sind doch konstant -->
const_iterator begin() const;Da hast du etwas falsch verstanden - das "const" dort bedeutet, daß die Methode begin() den darunterliegenden Container als konstant betrachtet. Der zurückgegebene Iterator ist trotzdem erst zur Laufzeit bestimmt (und kann sich selbst für einen gegebenen String auch zur Laufzeit ändern - ganz davon abgesehen, daß der tatsächlich verwendete String erst beim Aufruf feststehen wird).
-
Eigentlich eine einfache logische Überlegung:
Du kannst die Templatefunktion zur Laufzeit mit jeder beliebigen Collection benutzen? Dann sind die Iteratoren dieser Collection keine Compiletime-Konstanten
-
Kann evtl. noch einmal jemand zusammenfassen, wann ich bei einer Template Funktion meine Parameter als (1.) Template Parameter oder (2.) Funktions Parameter uebergeben kann/muss?
-
Als Template-Parameter kannst du Objekte angeben, die bereits für den Compiler bekannt sind - Typnamen (das dürfte das häufigste sein) und Ganzzahl-Literale (Achtung: Keine Gleitkomma-Literale). (eventuell noch etwas mehr, aber das fällt unter "Exoten")
Als regulären Funktionsparameter kannst du alles angeben, was sich zur Laufzeit in den entsprechenden Parametertyp umwandeln lässt.