templates + operatorüberladung = problem ;-)



  • hi leutz,
    hab da ein kleines problem, ich hab mir eine Matrixklasse definiert und wollte mir da einige operatoren zu definieren, jedoch bekomme ich eine mehrdeutigkeitsfehlermeldung, die ich mir nicht ganz erklären kann.

    verwenden tue ich: VC++ 6.0

    Fragmente aus der Klassendefinition:

    template <class T, unsigned int N, unsigned int M>
    class KMatrix
    { ... };
    
    template <class T, unsigned int N, unsigned int M, unsigned int P>
    KMatrix<T, N, P> operator * (const KMatrix<T, N, M>& A, const KMatrix<T, M, P>& B)
    { ... };
    
    template <class T, unsigned int N, unsigned int M>
    KMatrix<T, N, M> operator * (const KMatrix<T, N, M>& A, const T& x)
    { ... };
    
    template <class T, unsigned int N, unsigned int M>
    KMatrix<T, N, M> operator * (const T& x, const KMatrix<T, N, M>& A)
    { ... };
    

    Fragmente aus dem Code:

    KMatrix<double, 2, 4> E3;
    KMatrix<double, 4, 4> E4;
    
    E3 = E3 * E4;
    

    Fehler:

    error C2782: 'class KMatrix<T,N,M> __cdecl operator *(const T &,const class KMatrix<T,N,M> &)' : Vorlagenparameter 'T' ist mehrdeutig
            koennte 'double' sein
            oder       'class KMatrix<double,2,4>'
    

    das problem ist schon, dass er überhaupt nicht die richtige operatorüberladung wählt. vllt könnt ihr mir ja helfen, danke schon mal im voraus.

    PS: ich hoffe die details reichen für den anfang.



  • EDIT: laut dem Post unter mir lag ich mal wieder falsch.

    Also so wie ich das sehe liegt das Problem hier:

    KMatrix<T, N, M> operator * (const T& x, const KMatrix<T, N, M>& A)

    genauer gesagt weiss das Programm jetzt (meiner Meinung nach) nicht op das erste Argument genauso ist wie der erste Templateparameter von KMatrix<T,N,M> (also eben double) oder ob das jetzt für die Klasse steht.

    Bin aber selbst noch ANfänger also keine Garantie.

    ich denke eh dass du eher meintest:

    KMatrix<T, N, M> operator * (const KMatrix<T, N, M>& x, const KMatrix<T, N, M>& A)
    

    du musst ja je nach T anders verfahren



  • Nö, mein gcc kompiliert das ohne murren.
    Besorg dir doch VS2005, die 6.0er Version hat ein paar Macken.



  • @THX 1138: an das VS2005 komm ich jetz aber nicht ran, daher brauch ich was anderes hilfreiches 😉

    @Shinja: die einzelnen operatorüberladungen haben schon sinn, da das eine Skalar-Matrix -Multiplikationen sind und das andere eine Matrix-Matrix-Multiplikation ist.

    meiner meinung nach müsste der compiler durch die deklaration von E3 und E4 erkennen was gemeint ist, und den Matrix-Matrix-operator aufrufen. er versucht aber halt das in den Skalar-Matrix-operator zu stecken, was natürlich nicht funktionieren kann. der compiler interpretiert den code also von vornherein schon falsch. der template-Parameter T ist eigentlich schon durch die Matrizen E3 bzw E4 auf double festgelegt, weswegen ich nicht verstehe, wo das problem für den compiler ist.


  • Mod

    Der Code ist nicht das Problem, sondern dein Compiler. Grundsätzlich muss er nat. alle Überladungen prüfen, stellt dann aber fest, dass für die letzten beiden Überladungen, der Parameter T nicht eindeutig ist. Das ist im Prinzip kein Problem (SFINAE), da eine weitere Überladung existiert, für die alle Parameter ermittelt werden können. Möglicherweise kannst du dir mit ein paar Tricks behelfen, etwa indem du auf Überladung verzichtest, und statt dessen versuchst, das durch partielle Spezialisierung eines Klassentemplates zu erreichen. Ungefähr so:

    template<class T, class U>
    struct MatrixMul;
    
    template<class T, unsigned int N, unsigned int M, unsigned int P>
    struct MatrixMul< KMatrix<T, N, M>, KMatrix<T, M, P> >
    {
        typedef KMatrix<T, N, P> result_type;
        result_type operator()(const KMatrix<T, N, M>& A, const KMatrix<T, M, P>& B) const;
    };
    
    template <class T, unsigned int N, unsigned int M>
    struct MatrixMul< KMatrix< T, N, M>, T >
    {
        typedef KMatrix<T, N, M> result_type;
        result_type operator()(const KMatrix<T, N, M>& A, const T& x) const;
    };
    
    template <class T, unsigned int N, unsigned int M>
    struct MatrixMul< T, KMatrix< T, N, M> >
    {
        typedef KMatrix<T, N, M> result_type;
        result_type operator()(const T& x, const KMatrix<T, N, M>& A) const;
    };
    
    template<class T, class U>
    typename MatrixMul< T, U >::result_type operator*(const T& lhs, const U& rhs)
    {
        return MatrixMul< T, U >()( lhs, rhs );
    }
    

    Vielleicht geht das ja mit vc6



  • das sieht aber sehr unschön aus 😉
    ich bin grad dabei mir nen neuen compiler zu suchen, damit werde ich es dann nochmal probieren.



  • so ich hab mir jetzt die Visual C++ Express Edition installiert sowie die Platform SDK, jetzt hab ich aber das problem das folgender Fehler kommt:

    LINK : fatal error LNK1104: cannot open file 'odbc32.lib'
    

    jemand einen vorschlag wie ich das beheben kann.
    danke schonmal im voraus

    EDIT:

    LINK : fatal error LNK1104: cannot open file 'user32.lib'
    

    fehlt wohl auch 😞



  • ok hat sich erledigt, habs selbst hinbekommen.
    hatte einen fehler bei den Pfadangaben.


Anmelden zum Antworten