Templates



  • Hi,

    ich habe hier folgendes:

    #ifndef VEC2D_H
    #define VEC2D_H
    
    template <class T>
    class Vec2d
    {
    public:
        Vec2d(T x = 0, T y = 0)
        {
            p[0] = x;
            p[1] = y;
        }
    
        Vec2d(T p_[2])
        {
            p[0] = p_[0];
            p[1] = p_[1];
        }
    
        template <class T2>
        Vec2d(const Vec2d<T2> &other)
        {
            p[0] = static_cast<T>(other.p[0]);
            p[1] = static_cast<T>(other.p[1]);
        }
    
        template <class T2>
        Vec2d<T> operator+(const Vec2d<T2> &other)
        {
            return Vec2d<T>(
                p[0] + static_cast<T>(other.p[0]),
                p[1] + static_cast<T>(other.p[1])
            );
        }
    
        T p[2];
    };
    
    #endif
    
    // main.cpp
    
    #include "vec2d.h"
    
    #include <iostream>
    
    using namespace std;
    
    int main()
    {
        Vec2d<int> i(1, 3);
        Vec2d<float> f(1.5f, 6.7f);
    
        cout << (i + f).p[0] << endl; // ->  2
        cout << (f + i).p[0] << endl; // ->  2.5
    }
    

    Das Problem ist also, dass die Addition von Vektoren verschiedenen Typs nicht kommutativ ist. Kann man sowas irgendwie elegant loesen, zB. das kommutative Verkalten wie wenn man int- und floatwerte addiert?

    mfg und danke,
    Gunnar



  • Das Problem ist also, dass die Addition von Vektoren verschiedenen Typs nicht kommutativ ist. Kann man sowas irgendwie elegant loesen, zB. das kommutative Verkalten wie wenn man int- und floatwerte addiert?

    Ja. Kann man. Stichwort Promotion Traits:

    template <class T, class U>
    struct Promote
    {
    // Musst du entscheiden, ob das für deine Situation so clever ist.
    // Gibt es keine Spezialisierung, hast du hier eine endlose
    // Rekursion.
    typedef typename Promote<U, T>::Result Result;
    };
    
    // für zwei gleiche Typen ist das Ergebnis klar
    template <class T>
    struct Promote<T, T>
    {
        typedef T Result;
    };
    
    template <class T>
    struct Promote<T, long double>
    {
    typedef long double Result;
    };
    
    template <class T>
    struct Promote<T, double>
    {
    typedef double Result;
    };
    
    template <class T>
    struct Promote<T, float>
    {
    typedef float Result;
    };
    // Das selbe für die ints
    
    template <class T>
    class Vec2d
    {
    public:
        template <class U>
        Vec2d(U x, U y)
        {
            p[0] = x;
            p[1] = y;
        }
    //...
    template <class U, class T2>
    friend 
    Vec2d<typename Promote<U, T2>::Result> 
    operator+(const Vec2d<U>&, const Vec2d<T2> &);
    private:
         T p[2];
    };
    template <class T, class T2>
    Vec2d<typename Promote<T, T2>::Result> 
    operator+(const Vec2d<T>& lhs, const Vec2d<T2> &rhs)
    {
        return Vec2d<typename Promote<T, T2>::Result>(
                lhs.p[0] + rhs.p[0],
                lhs.p[1] + rhs.p[1]
            );
    }
    
    int main()
    { 
        Vec2d<int> i(1,2);
        Vec2d<double> d (1,3);
        Vec2d<double> a = d + i;
    }
    


  • jup so designproblem designproblem

    [ Dieser Beitrag wurde am 08.04.2003 um 23:45 Uhr von Dimah editiert. ]



  • Klasse; danke fuer die prompte Antwort!


Anmelden zum Antworten