Typauflösung bei template
-
Folgendes Problem :
struct convert_ex { template<typename other_string_type,typename result_string_type> result_string_type operator()(const other_string_type &Arg) const { return result_string_type(Arg.begin(),Arg.end()) ; } }; string Str1="test" ; convert_ex aConverter ; string Str2=aConverter(Str1) ;Der Compiler meldet mir den Fehler "error: no match for call to `(convert_ex) (std::string&)'"
Der Compiler müsste doch dies auflösen können, oder liege ich hier komplett falsch.Besten Dank für eure Bemühungen.
-
Wo soll result_string_type herkommen?
-
Der Ausdruck "string Str2=aConverter(Str1) ; " sollte doch dem Compiler sagen was ich will ?
-
case schrieb:
Der Ausdruck "string Str2=aConverter(Str1) ; " sollte doch dem Compiler sagen was ich will ?
Nein, zumal Rückgabewerte nicht zwangsweise ausgewertet werden müssen.
-
asc schrieb:
case schrieb:
Der Ausdruck "string Str2=aConverter(Str1) ; " sollte doch dem Compiler sagen was ich will ?
Nein, zumal Rückgabewerte nicht zwangsweise ausgewertet werden müssen.
string Str2=aConverter(Str1) ;ist kein Ausdruck, sondern eine Definition. Der initialisierende Ausdruck darin ist
aConverter(Str1)und hieraus kann der Rückgabetyp nicht ermittelt werden. Eine direkte Deduktion des Rückgabetyps erfolgt nur bei Konvertierungsoperatoren - klar, denn hier ist ja die Konvertierung in einen bestimmten Zieltyp überhaupt erst der Grund für den Funktionsaufruf.
-
Ok, überzeugt.
Dann muss ich mein Problem anders an gehen.
Trotzdem danke..
-
du musst den result-Typ in irgendeiner Weise mitgeben, und zwar entweder als Argument (direkt oder indirekt) oder explizit als Templateparameter angeben. Beispiele:
Expliziter templateparameter bei der Funktion
struct convert_ex { template<typename result_string_type, typename other_string_type> //beachte: result_type zuerst, damit man den zweiten parameter weglassen kann result_string_type operator()(const other_string_type &Arg) const { return result_string_type(Arg.begin(),Arg.end()) ; } }; /*...*/ string Str2=aConverter.operator()<string>(Str1); //eklig, macht den nutzen in der Schreibweise mit op() zunichteExpliziter Templateparameter beim struct
template <class result_string_type> struct convert_ex { template<typename other_string_type> result_string_type operator()(const other_string_type &Arg) const { return result_string_type(Arg.begin(),Arg.end()) ; } }; /*...*/ convert_ex<string> aConverter; string Str2=aConverter(Str1); MyString Str3 = aConverter(Str1); // FEHLER: convert_ex<string> kann nicht in MyString konvertieren, ein ganz klarer Nachteil!Ermitteln des Typs aus einem zusätzlichen Argument:
struct convert_ex { template<typename result_string_type, typename other_string_type> result_string_type& operator()(const other_string_type &Arg, result_string_type& res) const { res = result_string_type(Arg.begin(),Arg.end()) ; return res; } }; /*...*/ string Str2; aConverter(Str1, Str2); //Nachteil: keine initialisierung von Str2 sondern eine Zuweisung. Str2 muss bereits bestehen.über einen Tag:
template <typename string_type> struct StringTypeTag {}; struct convert_ex { template<typename result_string_type, typename other_string_type> result_string_type& operator()(const other_string_type &Arg, StringTypeTag<result_string_type>) const { return result_string_type(Arg.begin(),Arg.end()) ; } }; /*...*/ string Str2=aConverter(Str1, StringTypeTag<string>());Am Einfachsten wäre es wohl als freie Funktion, das wäre von allem etwas:
template<typename result_string_type, typename other_string_type> //beachte: result_type zuerst, damit man den zweiten parameter weglassen kann result_string_type ConvertString(const other_string_type &Arg) { return result_string_type(Arg.begin(),Arg.end()) ; } /*...*/ string Str2 = ConvertString<string>(Str1);
-
Danke pumuckl,
Das bringt mich einen guten Schritt vorwärts.