idee für rückgabe mehrerer werte



  • der thread weiter unten hat mich auf die idee gebracht man könnte da doch so ein lustiges templategewurstel machen. ich bin leider net so gut im erklären von dem zeugs, also hier einfach mal ein schnell zusammengecodetes beispiel wie ich mir das vorstelle (getestet mit g++ 3.2):

    //das templategewurstel
    template <class T1, class T2>
    struct return_pair_impl
    {
       return_pair_impl(T1 &r1, T2 &r2) : return1(r1), return2(r2) {}
       T1 return1;
       T2 return2;
    };
    
    template <class T1, class T2>
    return_pair_impl<T1, T2> return_pair(T1 r1, T2 r2)
    { return return_pair_impl<T1, T2>(r1, r2); }
    
    template <class T1, class T2>
    struct assign_pair_impl
    {
       assign_pair_impl(T1 &v1, T2 &v2) : var1(v1), var2(v2) {}
       template<class A1, class A2>
       return_pair_impl<A1, A2>& operator=(return_pair_impl<A1, A2> p)
       { var1=p.return1; var2=p.return2; return p; }
       T1 &var1;
       T2 &var2;   
    };
    
    template <class T1, class T2>
    assign_pair_impl<T1, T2> assign_pair(T1 &v1, T2 &v2)
    { return assign_pair_impl<T1, T2>(v1, v2); }
    
    //das obligate anwendungsbeispiel
    return_pair_impl<double, int> function()
    {
       return return_pair(3.14159, 42);
    }
    
    int main()
    {
       double pi;
       int answer;
       assign_pair(pi, answer)=function();
       std::cout << pi << ' ' << answer << std::endl;
    }
    

    was haltet ihr von der idee (nur die idee nicht die implementierung 🙂 )?



  • Warum nicht einfach via std::pair?



  • weil mir

    pair<double, int> p= function();
    pi = p.first;
    answer = p.second;
    

    weniger gut gefällt als

    assign_pair(pi, answer)=function();
    

    find ich 🙂



  • die Idee ist gut - allerdings funktioniert es nicht mit Referenzen 😞



  • so habe die sinnlose return_pair klasse rausgelassen und das stl::pair verwendet.

    hmm jetzt gerade so spontan, könnte man nicht dieses refernzen problem lösen indem man doch ein eigenes pair schreibt und das dann für refernzen partiel spezialisiert? hmm ich beschäftig mich mal damit, oder zumindest morgen.

    template <class T1, class T2>
    struct assign_pair_impl
    {
       assign_pair_impl(T1 &v1, T2 &v2) : var1(v1), var2(v2) {}
       template<class A1, class A2>
       std::pair<A1, A2>& operator=(std::pair<A1, A2> p)
       { var1=p.first; var2=p.second; return p; }
       T1 &var1;
       T2 &var2;   
    };
    
    template <class T1, class T2>
    assign_pair_impl<T1, T2> assign_pair(T1 &v1, T2 &v2)
    { return assign_pair_impl<T1, T2>(v1, v2); }
    
    std::pair<double, int> function()
    {
       return std::make_pair(3.14159, 42);
    }
    
    int main()
    {
       double pi;
       int answer;
       assign_pair(pi, answer)=function();
       std::cout << pi << ' ' << answer << std::endl;
    }
    


  • Jetzt gefällt mir zumindest die Implementierung immer noch nicht. 😉

    Ne, im Ernst, ich brauche das eigentlich nicht so oft, dass ich mehrere Werte zurückgebe.
    Wenn ich nen Fehler auslösen will, schmeiß ich eine Exception und mir fällt jetzt spontan kein Grund ein, mehrere Werte zurückzugeben. Vielleicht könnt ihr mir ja mal auf die Sprünge helfen?! 😋



  • was weis ich. vielleicht hat man in einem parser eine funktion readnumber(string, pos) da will man dann die gelesene zahl und die stringposition nach der zahl zurückgeben, oder so. klar kann man das auch anders umgehen, aber vielleicht will wer mal sowas.

    mfg japro



  • Ich will nichts gegen deine Idee sagen. Ich persönlich bin nur irgendwie der Meinung, dass ein Design Problem vorliegt, wenn man mehrere Rückgabewerte braucht. Aber das kann natürlich jeder sehen, wie er will. 🕶

    Und um deine Lösung zu kritisieren, müsste ich sie sowieso erstmal verstehen. 😃



  • Optimizer schrieb:

    Ich will nichts gegen deine Idee sagen. Ich persönlich bin nur irgendwie der Meinung, dass ein Design Problem vorliegt, wenn man mehrere Rückgabewerte braucht.

    Ich nicht. Die STL verwendet pair auch zum returnen von mehreren Werten.



  • IMHO ist es in den Fällen, wo man mehrere Rückgabewerte braucht, meistens sauberer, ein eigenes struct dafür zu erstellen.



  • Shade Of Mine schrieb:

    die Idee ist gut - allerdings funktioniert es nicht mit Referenzen 😞

    so hab mal schnell ein eigenes pair gebastelt. jetzt gehts auch mit referenzen. (ich übernemne keine garantie)

    template<class T1, class T2>
    struct pair {
       pair(const T1& f, const T2& s) : first(f), second(s) {}
    
       T1 first;
       T2 second;
    };
    
    template<class T1, class T2>
    struct pair<T1, T2&> {
       pair(const T1& f, T2& s) : first(f), second(s) {}
    
       T1 first;
       T2& second;
    };
    
    template<class T1, class T2>
    struct pair<T1&, T2> {
       pair(T1& f, const T2& s) : first(f), second(s) {}
    
       T1& first;
       T2 second;
    };
    
    template<class T1, class T2>
    struct pair<T1&, T2&> {
       pair(T1& f, T2& s) : first(f), second(s) {}
    
       T1& first;
       T2& second;
    };
    
    template <class T1, class T2>
    pair<T1, T2> make_pair(const T1 &f, const T2 &s)
    { return pair<T1, T2>(f, s); }
    
    template <class T1, class T2>
    struct assign_pair_impl {
       assign_pair_impl(T1 &v1, T2 &v2) : var1(v1), var2(v2) {}
       template<class A1, class A2>
       pair<A1, A2>& operator=(pair<A1, A2> p)
       { var1=p.first; var2=p.second; return p; }
       T1 &var1;
       T2 &var2;
    };
    
    template <class T1, class T2>
    assign_pair_impl<T1, T2> assign_pair(T1 &v1, T2 &v2)
    { return assign_pair_impl<T1, T2>(v1, v2); }
    
    pair<double, int&> function()
    {
       double pi = 3.14159;
       static int answer = 42;
       return pair<double, int&>(pi, answer);
    }
    
    int main()
    {
       double pi;
       int answer;
    
       assign_pair(pi, answer)=function();
       std::cout << pi << ' ' << answer << std::endl;
    }
    


  • @japro
    Hast du dir schon mal boost::tuple angeschaut? Die Lib bietet dir alles, was du hier nachbildest (und mehr natürlich), ist sorgfältig getestet und wird außerdem Teil des neuen C++ Standards sein.



  • hmpf, das musste ja sein.


Anmelden zum Antworten