überprüfen von template variable auf bestimmten typ



  • Wenn jede der abgeleiteten Klassen ihren eigenen Typ zurückgeben soll, wirst du nur schwer eine gemeinsame Schnittstelle finden.



  • sie soll ja nicht ihren eigenen Typen zurückgeben, eigentlich sollen ALLE long und double unterstützen (also für den Anfang)...
    Wenn das ganze jetzt allerdings erweitert werden soll, dass alle nativen Datentypen unterstützt werden sollen, dann hieße das, dass es dabei auch ein ziemliches durcheinander gibt. Ich habe derzeit auch noch das Problem, dass es eigentlich gar keinen Wert so direkt gibt in der Basis-Klasse, der Wert kommt erst in der abgeleiteten Klasse hinzu, von daher kann ich das ganze auch nicht ausimplementieren. Für mich wäre es ja schon genug, wenn ich eine Funktionsdeklaration finden könnte, die allgemein genug ist, dass ich in der abgeleiteten Klasse anschließend mit Templates arbeiten kann.



  • Schon allein das long und double unterstützt werden soll, ist schon problematisch. Und was heißt "ALLE"???

    Irgendwie ganz schön strange was du da machen willst. Man könnte höchstens über boost::any nachdenken. Oder wenn es keine Templates sein dürfen, mußt du halt ein void* zurück geben, und derjenige muß casten.



  • das mit dem void * habe ich mir auch schon überlegt, nur das mit dem Cast finde ich halt ein wenig schwierig, vor Allem in Richtung setzen (so mit Typprüfung)...
    ALLE bedeutet, dass alle erbenden Klassen die Konvertierungsmöglichkeiten prinzipiell unterstützen sollen.
    Jetzt habe ich mir eine Version geschrieben, die zwei Template-Parameter besitzt, in der Basisklasse und in der erbenden Klasse wird einer davon spezialisiert, allerdings erhalte ich die Fehlermeldung "illegal use of explicit template arguments". Gibt es da eine Möglichkeit das zu lösen, mein Code sieht wie folgt aus:
    Basisklasse:

    template <typename T, typename T1> T Convert ()
    {
    //...
    }
    

    abgeleitet:

    template <typename T> T Convert<std::string> ()
    {
    }
    

    Allerdings geht dies nicht, ich hoffe, irgendwer kann mir nun helfen



  • Sorry Vorden, ich hatte vergessen (so wie Braunstein richtig angemerkt hat), daß man nur Klassentemplates partiell spezialisieren kann (falls du dich von meinem Code hast inspirieren lassen?).

    Trotzdem verstehe ich den Sinn deiner Konvertierungstemplates immer noch nicht?
    Wenn du einfach nur Konvertierungen nach String- und zurück brauchst, dann würde ich über die Stringstreams gehen:

    template<class T> string toStr(const T& t)
    {
    	std::ostringstream str;
    
    	str << t;
    
    	return str.str();
    }
    
    template<class T> T fromStr(const string& s, const T& def = T())
    {
    	std::istringstream str(s);
    	T t = def;
    
    	str >> t;
    
    	return t;
    }
    

    Ansonsten müßtest du für beliebige Datentypen die Funktion 'Convert' mit den jeweiligen Datentypen überladen (jedoch darf sich die Funktion nicht alleine im Rückgabewert unterscheiden, d.h. "int Convert()" und "float Convert()" geht nicht!!!).

    Alternativ müßtest du dann jeweils eine Klasse (bzw. Struktur) darum packen:

    template<typename R>
    struct Convert
    {
      template <typename T>
      static R Do(T t) { return R(t); }
    };
    
    // Aufruf, z.B.
    int x = Convert<int>::Do(42.123f);
    

    Du könntest jetzt dann entsprechend des Rückgabetypes spezialisieren:

    template<>
    struct Convert<int>
    {
      template <typename T>
      static int Do(T t) { std::cout << t; return int(t); }
    
      static int Do(std::string s) { return 0; } // Überladung
    };
    
    // Aufruf z.B.
    int x = Convert<int>::Do(42.123f); // float->int
    int y = Convert<int>::Do(std::string("hallo")); // string->int
    

    Mehr fällt mir aber auch nicht mehr ein und ich hoffe, ich habe dich (in Ansätzen) richtig verstanden, was du vorhast???



  • jo, schon, das mit der Spezialisierung ist soweit richtig, allerdings bleibt das Problem dabei trotzdem bestehen, dass ich mit virtual nicht weiter komme... und das ist genau das, was ich bräuchte. Habe es jetzt wie folgt gelöst:
    Ich habe ein allgemeines Template und in der abgeleiteten Klasse die entsprechend spezialisierten Templates. Ich hoffe, dass das den gewünschten Effekt bringt. Das mit der partiellen Spezialisierung habe ich inzwischen auch gefunden, also, dass es lediglich auf Klassenebene möglich ist. Habe mir auch irgendwie ein Interface überlegt, welches entsprechend angebunden wird als "Converter" und dann eben "DoConvert" des entsprechenden Interfaces aufgerufen wird. Das muss ich mir nochmal durch den Kopf gehen lassen, ob die direkte Implementierung oder der Weg über das Interface sinnvoller sind.
    Intern soll auch die Konvertierung über die stringstreams ablaufen, nur der Punkt daran ist eben, dass ich die Konvertierung vom Anwender fernhalten wollte und möglichst generisch halten wollte (das ganze bezieht sich auf eine Bibliotheksfunktion, die später von Entwicklern in der Firma benutzt werden soll).
    Von daher wollte ich das mit den stringstreams weg kapseln, wenn jetzt eine "bool ReadInt (int * val)" aufruft, soll er halt auch sein int kriegen (dass es sich um ein bool handelt als Rückgabewert und nicht der Wert als Rückgabewert angegeben wird, hat andere Gründe.



  • bool ReadInt (int * val);

    Ganz schlechtes Design!

    Damit hast du wieder eine "old-school" C Funktion erzeugt (oder mußt du ein C-API entwickeln?)
    Besser wären auf jeden Fall Referenzen bzw. Ausnahmen etc.


Anmelden zum Antworten