datentypunabhängige Methoden?



  • Hallo,

    ich möchte eine Methode schreiben, die unabhängig vom Typ des Eingabeargumentes eine Verarbeitung vornimmt. Bisher mache ich das per Überladung nach dem Schema:

    void doPrint(int x) {
     printf("%i", x);
    }
    
    void doPrint(double x) {
     printf("%f", x);
    }
    
    usw.
    

    Jetzt möchte ich nicht für jeden simplen Datentyp eine eigene Methode schreiben. Geht das auch eleganter? Ich denke da an so ein (theoretisches) Konstrukt:

    void doPrint(<universaltyp> x) {
     switch (typeof(x)) {
       int: printf("%i", x);
       double: printf("%f", x);
       default: printf("error");
     }
    }
    

    Gruß, Thomas



  • Ich denke die Angaben was Du machen willst sind zu ungenau... Wenn es wirklich nur um eine Ausgabe des richtigen Typs auf stdout geht nimmt man doch eher ein Template, aber ich denke Du möchtest in Wirklichkeit noch etwas mehr in den Funktionen machen.

    template<typename Ty>
    void doPrint(const Ty& x) {
      cout << x;
    }
    

    Funktioniert vollautomatisch für alle Datentypen für die es ein ostream& operator<< gibt.

    Sowas wie einen Universaltyp den man zru Laufzeit auflösen kann gibt es nicht. Evtl. über Template-Spezialisierung?

    template<typename Universal>
    void doPrint(const Universal& x)
    {
      printf("error");
    }
    
    template<>
    void doPrint(const int& x)
    {
      printf("%i", x);
    }
    
    template<>
    void doPrint(const double& x)
    { 
      print("%f", x);
    }
    

    Hm, ist nur auch wieder für jeden Typ eine Methode.



  • Ja, mit C++ I/O Streams und Templates.
    Da du printf in deinem Code stehen hast, hoffe ich nicht das du aus der C-Ecke kommst.

    Denn sonst kannst du beides vergessen 😃

    template<typename type> void print(const type& x)
    {
       cout <<x;
    }
    

    Bei den Artikel sollte auch noch was dazu stehen....





  • Ich danke euch.
    Mit Templates hab ich mich noch nicht weiter beschäftigt, aber das Echo sagt mir, dass ich es mal tun sollte. 😉



  • und wer schon

    template<typename type> void print(const type& x)
    {
       cout <<x;
    }
    

    schreibt, der kann normal auch

    cout <<x;
    

    schreiben^^



  • otze schrieb:

    und wer schon

    template<typename type> void print(const type& x)
    {
       cout <<x;
    }
    

    schreibt, der kann normal auch

    cout <<x;
    

    schreiben^^

    Jo, schon klar 😃 sollte ja nur seinem Beispiel angepasst werden.



  • otze schrieb:

    und wer schon

    template<typename type> void print(const type& x)
    {
       cout <<x;
    }
    

    schreibt, der kann normal auch

    cout <<x;
    

    schreiben^^

    ich glaube, du hast da was übersehen, otze.

    #include <iostream>
    #include <vector>
    #include <algorithm>
    
    using namespace std;
    
    template<typename T>
    void print(const T &x) { cout << x << endl; }
    
    int main()
    {
        vector<int> v;
        v.push_back(43);
        v.push_back(42);
        v.push_back(39);
        for_each(v.begin(), v.end(), print<int>);
    }
    

    klar kann man auch schreiben:

    #include <iostream>
    #include <vector>
    #include <algorithm>
    #include <iterator>
    
    using namespace std;
    
    int main()
    {
        vector<int> v;
        v.push_back(43);
        v.push_back(42);
        v.push_back(39);
        copy(v.begin(), v.end(), ostream_iterator<int>(cout, "\n"));
    }
    

    aber wenn man das an 1000 stellen verwendet hat und plötzlich jede ausgabe verändert werden soll, steht man natürlich besser da, wenn man nur die print-Funktion anzupassen braucht.



  • Ich möchte die Typumwandlung vereinheitlichen.

    In einer XML-Datei im UTF-8 Format sollen verschiedene Daten abgelegt werden, dazu ist es notwendig, den jeweiligen Typ in ein Wide Character Format umzuwandeln.

    BSTR int2BSTR(int n)
    {
    	WCHAR chBuf[60];
    	swprintf(chBuf, L"%i", n);
    	return SysAllocString(chBuf);
    }
    
    BSTR float2BSTR(float f)
    {
    	WCHAR chBuf[60];
    	swprintf(chBuf, L"%f", f);
    	return SysAllocString(chBuf);
    }
    

    Hier wäre es ja zum Beispiel sinnvoll, wenn die erste Methode auch Untermengen von Integer verarbeiten könnte (char, byte, usw.), während sich die zweite Methode auch double vornehmen könnte.

    Ist die Bezugnahme auf spezielle Typen das, was mit Template-Spezialisierung gemeint ist?

    Wie sage ich beispielsweise der ersten Methode, dass sie int, char und byte annehmen soll?



  • Thomas++ schrieb:

    Hier wäre es ja zum Beispiel sinnvoll, wenn die erste Methode auch Untermengen von Integer verarbeiten könnte (char, byte, usw.), während sich die zweite Methode auch double vornehmen könnte.

    Kann sie - Stichwort "implizite Typumwandlung"

    (wobei ich eher eine double2BSTR() verwenden würde, die (auch) mit float-Werten gefüttert werden kann)

    PS: Für diese Umwandlung solltest du auch lieber C++ Metohden verwenden:

    template<typename T>
    BSTR toBSTR(const T& val)
    {
      wstringstream strm;
      strm<<val;
      return SysAllocString(strm.str().c_str());
    }
    

    (das "erschlägt" jeden Datentyp, der auf einen wchar_t-Stream ausgegeben werden kann)


Anmelden zum Antworten