Operator + : template-Argument für "T" konnte nicht hergeleitet werden?



  • Vielen Dank KasF,

    so wie du es schreibst, hatte ich es auch zuerst unter MSVSc++ programmiert, (wie in deinem Link habe ich cout, <<, >> auch noch überladen, das klappt bei MSVSc++ und gcc/c++.)

    Der folgende Code funktioniert mit MS Visual Studio 2005 aber er funktioniert nicht mit gcc/c++ (wxDev-C++ 6.10-2):

    // add scalar to components
       matrix<T> operator + (const T c);
       friend matrix<T> operator + (const T c, const matrix<T>& m );
       //// friend matrix<T> (::operator + <>)(const T c, const matrix<T>& m );
    
       // sub scalar from components
       matrix<T> operator - (const T c);					          
       // sub components from const scalar
       friend matrix<T>  operator - (const T c, const matrix<T>& m );
       //// friend matrix<T> (::operator - <>)(const T c, const matrix<T>& m );
    
       // mult all matrix components by scalar c
       matrix<T> operator * (const T c);
       friend matrix<T> operator * (const T c, const matrix<T>& m );
       //// friend matrix<T> (::operator * <>)(const T c, const matrix<T>& m );
    
    Meldungen bei gcc/c++ (wxDev-C++ 6.10-2):  
    
     Warnungen:  
       65 D:\Programming\000-devcpp\matrix.h [Warning] friend declaration `matrix<T> 
       operator+(T, const matrix<T>&)' declares a non-template function 
       65 D:\Programming\000-devcpp\matrix.h [Warning] (if this is not what you intended, 
       make sure the function template has already been declared and add <> after the 
       function name here) -Wno-non-template-friend disables this warning 
    
    Fehler:   
       [Linker Error] undefined reference to `operator*(double, matrix<double> const&)' 
       [Linker Error] undefined reference to `operator*(double, matrix<double> const&)' 
       [Linker Error] undefined reference to `operator-(double, matrix<double> const&)' 
       [Linker Error] undefined reference to `operator*(double, matrix<double> const&)' 
       [Linker Error] undefined reference to `operator+(double, matrix<double> const&)'
    

    Der folgende Code funktioniert mit gcc/c++ (wxDev-C++ 6.10-2) aber er funktioniert nicht mit MS Visual Studio 2005 :

    // add scalar to components
       matrix<T> operator + (const T c);
       //// friend matrix<T> operator + (const T c, const matrix<T>& m );
       friend matrix<T> (::operator + <>)(const T c, const matrix<T>& m );
    
       // sub scalar from components
       matrix<T> operator - (const T c);
    
       // sub components from const scalar
       //// friend matrix<T> operator - (const T c, const matrix<T>& m );
       friend matrix<T> (::operator - <>)(const T c, const matrix<T>& m );
    
       // mult all matrix components by scalar c
       matrix<T> operator * (const T c);
       //// friend matrix<T> operator * (const T c, const matrix<T>& m );
       friend matrix<T> (::operator * <>)(const T c, const matrix<T>& m );
    
    Fehlermeldungen MS Visual Studio 2005:
    
    Fehler	1	error C2783: "matrix<T> operator +(const T,const matrix<T> &)":
    template-Argument für "T" konnte nicht hergeleitet werden. matrix.h	69
    
    Fehler	2	error C2783: "matrix<T> operator *(const T,const matrix<T> &)":
    template-Argument für "T" konnte nicht hergeleitet werden. matrix.h	87
    

    Nachdem die Fehler bei gcc aufgetreten waren, hatte ich mittels googlen herausgefunden, dass man anstelle

    friend matrix<T> operator - (const T c, const matrix<T>& m );
    

    nun bei gcc/c++ und anderen c++ Compilern neuerdings (seit 2003?)

    friend matrix<T> (::operator - <>)(const T c, const matrix<T>& m );
    

    schreiben muss. Offensichtlich kann MSVSC++ nur was mit der alten Schreibweise anfangen.
    Weiss jemand dazu Näheres, und besonders: wie kann ich das Problem bei MS umgehen? (Ich möchte hier möglichst keine #ifdefs schreiben)

    Viele Grüsse von tesu



  • tesuji schrieb:

    // add scalar to components
       matrix<T> operator + (const T c);
       friend matrix<T> operator + (const T c, const matrix<T>& m );
       //// friend matrix<T> (::operator + <>)(const T c, const matrix<T>& m );
    
       // sub scalar from components
       matrix<T> operator - (const T c);					          
       // sub components from const scalar
       friend matrix<T>  operator - (const T c, const matrix<T>& m );
       //// friend matrix<T> (::operator - <>)(const T c, const matrix<T>& m );
    
       // mult all matrix components by scalar c
       matrix<T> operator * (const T c);
       friend matrix<T> operator * (const T c, const matrix<T>& m );
       //// friend matrix<T> (::operator * <>)(const T c, const matrix<T>& m );
    
    Meldungen bei gcc/c++ (wxDev-C++ 6.10-2):  
    
     Warnungen:  
       65 D:\Programming\000-devcpp\matrix.h [Warning] friend declaration `matrix<T> 
       operator+(T, const matrix<T>&)' declares a non-template function 
       65 D:\Programming\000-devcpp\matrix.h [Warning] (if this is not what you intended, 
       make sure the function template has already been declared and add <> after the 
       function name here) -Wno-non-template-friend disables this warning 
    
    Fehler:   
       [Linker Error] undefined reference to `operator*(double, matrix<double> const&)' 
       [Linker Error] undefined reference to `operator*(double, matrix<double> const&)' 
       [Linker Error] undefined reference to `operator-(double, matrix<double> const&)' 
       [Linker Error] undefined reference to `operator*(double, matrix<double> const&)' 
       [Linker Error] undefined reference to `operator+(double, matrix<double> const&)'
    

    Die Linkerfehler kommen daher das du die friend funktion nicht bei der Deklaration definiert hast. ( siehe Link dbzgl. nochmal )

    So:

    // add scalar to components
       matrix<T> operator + (const T c);
       friend matrix<T> operator + (const T c, const matrix<T>& m )
       {
         // implementation
       }
       //// friend matrix<T> (::operator + <>)(const T c, const matrix<T>& m );
    
       // sub scalar from components
       matrix<T> operator - (const T c);					          
       // sub components from const scalar
       friend matrix<T>  operator - (const T c, const matrix<T>& m );
       {
         // implementation
       }
       //// friend matrix<T> (::operator - <>)(const T c, const matrix<T>& m );
    
       // mult all matrix components by scalar c
       matrix<T> operator * (const T c);
       friend matrix<T> operator * (const T c, const matrix<T>& m )
       {
         // implementation
       }
       //// friend matrix<T> (::operator * <>)(const T c, const matrix<T>& m );
    

    Dann sollte das in beiden Compilern funktionieren.

    Davon weiß ich noch gar nichts:

    nun bei gcc/c++ und anderen c++ Compilern neuerdings (seit 2003?)

    friend matrix<T> (::operator - <>)(const T c, const matrix<T>& m );
    

    Werde mich mal irgendwann darüber erkunden.;)

    Du könntest ja dir auch die ganze friend-Geschichte sparen und normale Funktion definieren, die über get-Funktion Zugriff auf die gebrauchten Daten haben, falls das in deinem Design schön aussieht.

    P.S.: Zudem gibts da noch ein paar Schönheitsfehler, die klären wir aber nachdem du das momentane Problem gelöst hast.



  • Zur Schreibweise: GCC kommt gut auch so zurecht:

    template<class T>
    Matrix<T> operator*(const T& zahl, const Matrix<T>& m) {
        Matrix<T> temp = m;
        return temp *= zahl;  // Aufruf von Member-operator*=(zahl)
    }
    

    Man kann dabei vollständig auf friend-Deklarationen verzichten, weil der Member-Operator operator*=() benutzt wird (den muss es natürlich geben).
    MSVC habe ich nicht, müsste es dem Posting nach aber auch können.
    Weiterer Vorteil: Nutzung desselben Codes in operator*(const T& zahl, const Matrix<T>& m) (global) und operator*=(const T& zahl) (member).



  • Hallo KasF,

    ich hatte übersehen, dass du

    friend matrix<T>::operator + (const T c, const matrix<T>& m );
    

    geschrieben hattest (mit zwei Doppelpunkten).

    Wenn ich diese Schreibweise verwende, bekomme ich folgende Fehlermeldung bei MSVSC++:

    Fehler 1 error C4430: Fehlender Typspezifizierer - int wird angenommen. Hinweis: "default-int" wird von C++ nicht unterstützt. matrix.h 70

    und bei gcc/c++ v:

    65 D:\Programming\000-devcpp\matrix.h ISO C++ forbids declaration of operator+' with no type 65 D:\\Programming\\000-devcpp\\matrix.hstatic int matrix<T>::operator+(T, const matrix<T>&)' must be either a non-static member function or a non-member function
    65 D:\Programming\000-devcpp\matrix.h [Warning] member functions are implicitly friends of their class

    vg. tesu



  • tesuji schrieb:

    H

    friend matrix<T>::operator + (const T c, const matrix<T>& m );
    

    Sorry, da hatte ich mich irgendwie vertippt/verdenkt :D. Sollte natürlich so aussehen:

    template <typename T> class matrix : public mave<T>
    {
     public:
    // ...
    friend matrix<T> operator+(const T c, const matrix<T>& m )
    {
      //imp.
    }
    // ...
    }
    

    Und nochmal "Hallo" und *verbeug* vor Herr UBr 🙂

    Edit: Mach das so wie UBr es gesagt hat, nicht so wie ich meinte mit get-Funktionen. So ist es natürlich Designtechnisch am schönsten ...



  • Vielen Dank, KasF und uBr für eure ausführliche Antworten. Ich hatt die friends nur eingeführt, weil ich bei den zweiten Definitionen immer die Fehlermeldung bekam, dass nur genau ein Parameter in der Parameterliste zulässig sei. Da hab ich mir wohl mit friend tiefergehende Probleme eingehandelt.

    Ich werde euere Vorschläge nun genau studieren und in meine Klasse einbauen. Dann melde ich mich wieder. (qKasF, ich freue mich, wenn du mich auf Schönheitsfehler hinweist. (Das ist meine erste größere Klassendefinition, und ich bin ja bereits über einige Fallstricke gestolpert. Die Sache mit (::operator - <>) und der forward-Deklaration hatte ich erst nach langem Suchen auf englischen Seiten gefunden, aber eure Deklaration ist schöner)

    Viele Grüsse von tesu



  • Hallo UBr,
    ich habe deinen Vorschlag umgesetzt und es funktioniert bei MSVC++ und gcc korrekt! Mein allergrößter Dank geht an dich (Ich fummelte an dieser Sache schon fast ein Woche rum).

    edit: KasF, du hattest die Lösung ja bereits ganz am Anfang gesagt, Zitat: "Die Linkerfehler kommen daher das du die friend funktion nicht bei der Deklaration definiert hast." Sorry, ich hätte da mal genauer Lesen sollen. Deshalb mein allergrößter Dank auch an dich.

    Hier ist der Code:

    // add scalar to components
       matrix<T> operator + (const T c);
    
       // add components to scalar (Alternative von UBr)
       friend inline matrix<T> operator + (const T c, const matrix<T>& m )
       { matrix<T> s(m); for (int i = 0; i < s.roco; i++) s.mat[i] += c; return s;}
    
       // sub scalar from components
       matrix<T> operator - (const T c);
    
       // sub components from const scalar (Alternative von UBr)
       friend matrix<T> operator - (const T c, const matrix<T>& m )
       { matrix<T> s(m);  for (int i = 0; i < s.roco; i++) s.mat[i] = c - s.mat[i];
         return s;}
    
       // mult all matrix components of m by scalar c
       matrix<T> operator * (const T c);
    
       // mult scalar c by all matrix components of m (Alternative von Ubr)
       friend inline matrix<T> operator * (const T c, const matrix<T>& m )
       { matrix<T> s(m); for (int i = 0; i < s.roco; i++) s.mat[i] *= c; return s;}
    

    Der Grund, warum ich die Operationen immer paarweise brauche ist, dass sowohl s+M als auch M+s berechenbar sein muss, wenn s ein Skalar und M eine Matrix ist. Die forward-Deklarationen sind bei deiner Lösung auch nicht mehr erforderlich.

    Auf die friends konnte ich jedoch (noch) nicht verzichten, da ohne sie sowohl bei gcc als auch MSc++ eine Lawine von Fehlern auftrat.

    Falls du weitere Schwachstellen im Code findest, bitte teile sie mir mit.

    Viele Grüsse von tesu



  • Naja, das ist zwar was ich dir von Anfang an vorgeschlagen habe, aber wurscht 🙂
    Das was UBr geschrieben hat, hast du ja auch noch nicht ganz umgesetzt.

    1.) Implentiere deine operator +,-,/ etc. mit +=,-=,/= etc. So wie es UBr vorgeschlagen hat. Somit hast du keinen doppelten Code was auch direkt Konsistenter ist.
    Nun brauchst du auch wie du im Beispiel siehst keine friends mehr. Mach das in deinem Code genauso.

    Beispiel:

    class MyClass {
    
        private:
                int zahl;
        public:
                MyClass() {}
    
                MyClass& operator+=(int z)
                {
                    zahl += z;
                    return *this;
                }
    
                const MyClass operator+(int z)
                {
                    return MyClass(*this) += z;
                }
    
    };
    
    const MyClass operator+(int z, const MyClass& obj)
    {
        return MyClass(obj) += z;
    }
    

    2.) Mache aus deinen "const T c"'s überall ein "const T& c". Man weiß ja nie was T sein könnte ...

    Das wars erstmal 😉

    Edit: Hab dein Edit nicht gesehen das ich zwischenzeitlich weg war ...



  • Danke KasF.

    dass ich aus const T c ein const T& c machen soll, liegt das daran, dass dann anstelle einer vollständigen Kopie eine Referenz auf c übergeben wird? Das wird dann Speicherplatz auf dem Stack einsparen und auch schneller laufen.

    vg. tesu



  • Nur so nebenbei: in der Declaration der Klasse selbst lässt man das "<T>" üblicherweise weg, also so:

    template <typename T> class matrix : public mave<T> 
    { 
     public: 
       //matrix<T> (unsigned row) : mave<T>(row){rangk=-1;} 
       matrix (unsigned row) : mave<T>(row){rangk=-1;} 
    
       // ...
    
       // ~ operator 
       //matrix<T> operator ~(){return matrix<T>(mave<T>::operator ~(/*-:)*/));} 
       matrix operator ~(){return matrix(mave<T>::operator ~(/*-:)*/));} 
    
       // assignment operators 
       //matrix<T>& operator  = (const T s); 
       matrix& operator  = (const T s);
    

    Ich weiss nichtmal ob das laut Standard überhaupt erlaubt ist das "<T>" beim ctor/dtor zu schreiben so wie du das machst. Bei Parametern-Typen/Return-Typ ist es ziemlich sicher erlaubt, nur eben auch unnötig.



  • tesuji schrieb:

    dass ich aus const T c ein const T& c machen soll, liegt das daran, dass dann anstelle einer vollständigen Kopie eine Referenz auf c übergeben wird? Das wird dann Speicherplatz auf dem Stack einsparen und auch schneller laufen.

    Ja so ist es, du ersparst somit schon viel ...

    Zudem würde ich das noch machen was hustbaer geschrieben hat und noch alle Rückgabewerte von op+,-,* und / zu const matrix<T> machen.

    Damit auch nicht ja jemand sowas machen kann:

    matrix<int> a,b,c;
    //...
    a + b = c;
    

    Dazu gibts aber noch was schönes von camper hier: http://c-plusplus.net/forum/viewtopic-var-p-is-1275887.html#1275887



  • hi liebes Forum,

    Ich habe euere Vorschläge nun in die Matrizenklasse übernommen:

    1. Alle binären Operatoren (+,-,,/) durch die zuvor definierten arithmetischen
    Zuweisungsoperatoren (+=,-=,
    =,/=) ersetzen. Das funktioniert nun bestens,
    und der Code ist wie KasF und UBr sagten viel übersichtlicher und
    konsistenter.

    2. const T s habe ich überall (wo es zulässig war) durch const T& s ersetzt. Mir
    ist nun klar, was das bedeutet.

    3. Den Vorschlag von hustbaer matrix<T> durch matrix zu ersetzen, wie in:
    matrix<T>& operator = (const T s); also: matrix& operator = (const T s);
    habe ich auch übernommen. Ich hatte die Schreibweise matrix<T> irgend wo
    gesehen und ohne Überlegung nachgeschrieben. Mir ist jetzt klar, dass es bei
    der Deklaration genügt nur matrix zu schreiben, weil das bereits eindeutig
    ist. Danke hustbaer!

    Hier der verbesserte Code:

    // numeric assignment operators
       matrix operator += (T s);
       matrix operator -= (T s);
       matrix operator *= (T s);
       matrix operator /= (T s);
       matrix operator += (const matrix<T>& m);
       matrix operator -= (const matrix<T>& m);
       matrix operator *= (const matrix<T>& m);
    
       // unary operators
       matrix operator + ();   // does nothing, yet satisfies true completeness
       matrix operator - ();   // changes signs of all components
       matrix operator ! ();   // inverse of matrix
    
       // binary operators
       // add scalar s to all components of matrix this: *this + s
       inline matrix operator + (const T& s)
        {matrix<T> a(*this); return (a += s);}
    
       // add scalar s to all components of matrix m:  c + a
       friend inline matrix operator + (const T& s, const matrix<T>& m )
        {matrix<T> a(m); return (a += s);}
    
       // sub scalar s from all components of matrix this: *this - s
       inline matrix operator - (const T& s)
        {matrix<T> a(*this); return (a -= s);}
    
       // sub all components of matrix m from scalar s:
       friend inline matrix operator - (const T& s, const matrix<T>& m )
        {matrix<T> a(m); return (a = -a + s);}
    
       // mult all matrix components by scalar c
       inline matrix operator * (const T& s)
        {matrix<T> a(*this); return (a *= s);}
    
       friend inline matrix operator * (const T& s, const matrix<T>& m )
        {matrix<T> a(m); return (a *= s);}
    
       // div all matrix components by scalar s
       matrix operator / (const T& s)
        {matrix<T> a(*this); return (a /= s);}
    
       // matrix to power p, a^p   (a*a ... *a, p-times)
       matrix operator ^ (int p)
         { matrix<T> m(*this); for (int i = 1; i < p; i++ ) m *= *this; return m;}
    

    Übrigens, ich habe auch "matrix to power p" so wie ihr das vorgeschlagen hat
    abgeändert in m *= *this !!! Die ganzen Matrizenmultiplikationen, die ich da programmiert hatte, sind nun einfach weg! Das ganze wird so langsam unheimlich kurz 😮

    Leider kann ich aber auf die friends (und damit auch auf die forward-Deklarationen zu Beginn der Klasse)
    immer noch nicht verzichten, denn wenn ich z.B. aus:

    // add scalar s to all components of matrix this: *this + s
       inline matrix operator + (const T& s)
        {matrix<T> a(*this); return (a += s);}
    
       // add scalar s to all components of matrix m:  c + a
       friend inline matrix operator + (const T& s, const matrix<T>& m )
        {matrix<T> a(m); return (a += s);}
    
    das mache:
    
       // add scalar s to all components of matrix this: *this + s
       inline matrix operator + (const T& s)
        {matrix<T> a(*this); return (a += s);}
    
       // add scalar s to all components of matrix m:  c + a
       inline matrix operator + (const T& s, const matrix<T>& m )
        {matrix<T> a(m); return (a += s);}
    

    bekommen ich immer noch diese Fehlermeldungen:

    gcc:
    71 D:\Programming\000-devcpp\matrix.h `matrix<T> matrix<T>::operator+(const T&, const matrix<T>&)
    [with T = int]' must take either zero or one argument

    MSVC++
    Fehler 1 error C2804: Binärer Operator '+' hat zu viele Parameter
    E:\matrix.h 71

    Ich dachte, da nun der Implementierungsteil der beiden Operatoren im Deklarationssteil steht, müssten die beiden überladenen Operatoren doch eindeutig unterscheidbar sein. Was kann da falsch sein?

    @KasF, du schreibst: ... und noch alle Rückgabewerte von op+,-,* und / zu const matrix<T> machen.

    Ist das z.B. so zu verstehen, dass ich für matrix<T> a(*this):

    // add scalar s to all components of matrix this: *this + s
       inline matrix operator + (const T& s)
        {const matrix<T> a(*this); return (a += s);}
    

    schreiben soll? Dann kann aber a += s nicht mehr ausgeführt werden (ich habs
    also falsch verstanden)

    Viele Grüsse von tesu



  • Die globalen (binären Operatoren sollten nicht innerhalb der Klasse deklariert werden, dann brauchen sie auch nicht friend zu sein. Beispiel:

    // matrix.h
    // hier ist die Klasse matrix. ...
    }; // Ende der Klasse
    // DANACH erst folgen die  binären Operatoren:
    template<class T>
    matrix<T> operator*(const T& zahl, const matrix<T> &m) {
        matrix<T> temp = m;
        return temp *= zahl; 
    }
    // ... usw
    

    friend ist nicht notwendig, weil keinerlei Zugriff auf interne Daten erfolgt, nur auf den Member-Operator, und der ist public.
    Innerhalb der Klasse stehen die Kurzform-Operatoren *= usw. Diese sollten aber nicht matrix zurückgeben, sondern matrix&, weil sonst eine unnötige Kopie erzeugt wird. Die letzte Anweisung in z.B. operator+=(...) ist return *this. Dann sind auch verkettete Rechnungen möglich wie a += b += c; Hoffentlich habe ich die angefragte Problemstellung richtig interpretiert.



  • Hi,

    tesuji schrieb:

    // numeric assignment operators
       matrix operator += (T s);
       matrix operator -= (T s);
       matrix operator *= (T s);
       matrix operator /= (T s);
       matrix operator += (const matrix<T>& m);
       matrix operator -= (const matrix<T>& m);
       matrix operator *= (const matrix<T>& m);
    

    Die ganzen Zuweisungsoperatoren ( nannte man die so ? ) müssen bzw sollten alle eine Refernz auf *this zurückgeben.

    Sowie wie in dem Code auf Seite 1 von mir:

    MyClass& operator+=(int z)
    {
         zahl += z;
         return *this;
    }
    

    Weil dies erstens perfomanter ist und zudem in einem weiter Ausdruck benutzt werden kann.

    tesuji schrieb:

    // add scalar s to all components of matrix m: c + a
    inline matrix operator + (const T& s, const matrix<T>& m )
    {matrix<T> a(m); return (a += s);}
    [/cpp]
    bekommen ich immer noch diese Fehlermeldungen:

    gcc:
    71 D:\Programming\000-devcpp\matrix.h `matrix<T> matrix<T>::operator+(const T&, const matrix<T>&)
    [with T = int]' must take either zero or one argument

    MSVC++
    Fehler 1 error C2804: Binärer Operator '+' hat zu viele Parameter
    E:\matrix.h 71

    Du musst den operator+(const T&, const matrix<T>&) global definieren, sowie in MyClass ( Seite 1 ).
    Durch das friend sind das ja keine Memberfunktionen. Damit sowas wie m1 = 3 + m2 funktioniert muss es ja eine globale Funktion geben die ein int und ein matrix<T> erwartet.
    Deswegen die op's global machen.

    Ein operator+(const T&, const matrix<T>&) als Member kann nicht funktionieren, einfaches Beispiel dazu:

    // op+(const T&, const matrix<T>&) ist global
    m1 = 3 + m2;
    // Compiler sucht für op+ was ein int und matrix als parameter hat -> gefunden
    
    // op+(const T&, const matrix<T>&) ist in Klasse
    m1 = m2 + m3;
    // Compiler sieht das als m1.operator=( m2.operator+(matrix) )
    // " m2.operator+(matrix)" m2 ist matrix, matrix hat ein op+(matrix)
    
    // op+(const T&, const matrix<T>&) ist in Klasse
    m1 = 3 + m2;
    // Compiler sucht für op+ was ein int und matrix als parameter hat, kann einen aber nicht finden, den es einen \3.operator+(matrix\ ja auch nicht gibt.
    

    tesuji schrieb:

    @KasF, du schreibst: ... und noch alle Rückgabewerte von op+,-,* und / zu const matrix<T> machen.

    Ist das z.B. so zu verstehen, dass ich für matrix<T> a(*this):

    // add scalar s to all components of matrix this: *this + s
       inline matrix operator + (const T& s)
        {const matrix<T> a(*this); return (a += s);}
    

    schreiben soll?

    Ne, so:

    // add scalar s to all components of matrix this: *this + s
       inline const matrix operator + (const T& s)
        { matrix<T> a(*this); return (a += s);}
    

    Edit: to slow ...



  • Hallo hustbaer, Br und KasF,
    ich hab nun fast alle eure Vorschläge übernommen und es funktioniert bereits sehr gut. Ich hänge allerdings immer noch mit den "friends" rum (ich hatte auch gedacht, dass das ja eigentlich keine Memberfunktionen sein müssen, aber es gibt immer noch Fehler, wenn ich die betreffenden Operatoren aus der Klassendeklaration rausnehme und in den Implementierungsteil stecke). Ich werde mich deshalb noch einmal melden, sobald ich ein paar Tests mit einer Primtivklasse, in der ich das Problem isolieren werde, gemacht habe, falls ich nicht weiterkommen sollte.

    Ich möchte an euer Forum ein ganz grosses Dankeschön sagen. Denn so schnell, ausführlich und geduldig wie ihr hier Fragen super professionell beantwortet, habe ich sonst noch nirgendwo erlebt. Ich habe unheimlich viel von euch gelernt. Danke! (In TechInfo wird bei uns die ganze c++ oop nur sehr dürftig vermittelt, ich glaube nun auch, dass unsere beiden Profs, da auch nicht so richtig den Überblick haben, denn wir haben mit C++ fast nur einfaches C gemacht).

    Hier will ich euch die ersten Rechenergebnisse mit den Matrizenoperatoren zeigen. Ich habe auch cout << überladen, und kann nun Matrizen ausgeben. Und die Indexe c(500, 333) funktionieren auch. Die Matrix c ist eine 2x4 Matrix, aber ihre Indexe sind so zu gebrauchen: c(501,335) = 10. Es werden aber nur 2x4 = 8 double allokiert. Hier die Ergebnisse:

    matrix<double> c(500, 501, 333, 336)
    
    c  = -1:
    -1      -1      -1      -1
    -1      -1      -1      -1
    
    Properties of matrix c:
    Rectangular matrix: 2 rows * 4 columns
    row subscripts from 500 to 501
    col subscripts from 333 to 336
    
    Components:
    -1      -1      -1      -1
    -1      -1      -1      -1
    
    c += 6:
    5       5       5       5
    5       5       5       5
    
    c -= 1:
    4       4       4       4
    4       4       4       4
    
    c *= 2:
    8       8       8       8
    8       8       8       8
    
    c /= 4:
    2       2       2       2
    2       2       2       2
    
    c = c+1:
    3       3       3       3
    3       3       3       3
    
    c = 3+c:
    6       6       6       6
    6       6       6       6
    
    c = c-2:
    4       4       4       4
    4       4       4       4
    
    c = 10-c:
    6       6       6       6
    6       6       6       6
    
    c = c*2:
    12      12      12      12
    12      12      12      12
    
    c = c/3:
    4       4       4       4
    4       4       4       4
    
    c = 2*c:
    8       8       8       8
    8       8       8       8
    
    Transpose c = ~c
    8       8
    8       8
    8       8
    8       8
    
    c *= ~c:
    256     256
    256     256
    
    c = 1 + 2*(c^2) - 6*(c^3) + 9*(c^4):
    3.08835e+011    3.08835e+011
    3.08835e+011    3.08835e+011
    
    Matrix c to be inverted (c(1,0) = c(0,1) = 1):
    3.08835e+011    1
    1       3.08835e+011
    
    Inverse c = !c:
    3.23797e-012    -1.04845e-023
    -1.04845e-023   3.23797e-012
    
    Identity I = !c * c:
    1       1.2326e-028
    0       1
    

    Viele Grüsse von tesu



  • tesuji schrieb:

    Ich möchte an euer Forum ein ganz grosses Dankeschön sagen. Denn so schnell, ausführlich und geduldig wie ihr hier Fragen super professionell beantwortet, habe ich sonst noch nirgendwo erlebt. Ich habe unheimlich viel von euch gelernt. Danke! (In TechInfo wird bei uns die ganze c++ oop nur sehr dürftig vermittelt, ich glaube nun auch, dass unsere beiden Profs, da auch nicht so richtig den Überblick haben, denn wir haben mit C++ fast nur einfaches C gemacht).

    Keine Ursache 😉 Solange hier jemand sein Probleme schön schildert und von uns nicht erwartet das wir irgendwas für ihn machen und er selbst lernwillig ist, helfen wir den Leuten hier gerne.

    Zudem lerne ich selber nur dadurch, in dem ich mich mit Problemen anderer beschäftige. Dann wird mal ab und zu da und hier nochmal nachgeschaut/-geblättert und so behalte ich auch einiges besser im Kopf, wenn ich etwas schreibe 😉


Anmelden zum Antworten