2017-12-17 7 views
-2

Es gibt eine generische Klasse Vector, die std :: array erweitert, und eine generische Klasse Expression, die die möglichen Ausdrücke der Vektoren definiert.Erstelle eigenen Operator ** in C++?

Zum Beispiel:

Vektor A ({1,2,3});

Vektor B ({2,2,2});

und die Ausdrücke:

A + B;

A * B;

A - B;

A/B;

Jetzt brauche ich diesen Ausdruck A ** B, der ein Doppel als die Skalarproduktion von zwei Vektoren A und B zurückgibt, das Ergebnis muss sein: 2 + 4 + 6 = 12. Das Problem ist die Implementierung von Operator ** !!!

Wie kann ich diesen Operator ** schreiben?

Meine Idee ist es, die Dereferenzierungsoperator * von Vector zu überlasten, die einen Zeiger zurückgibt und überlasten Sie dann die Struktur-Mul oder mehrfach operator * ... konnte diesen Fehler nicht lösen:

„keine geeignete Konvertierungsfunktion von "Expression < ...>" auf "double" existiert“

template<typename Left, typename Op, typename Right> class Expression { 
    const Left& m_left; 
    const Right& m_right; 

public: 
    typedef typename Left::value_type value_type; 

    // Standard constructor 
    Expression(const Left& l, const Right& r) : m_left{ l }, m_right{ r } {} 

    size_t size() const { 
     return m_left.size(); 
    } 

    value_type operator[](int i) const { 
     return Op::apply(m_left[i], m_right[i]); 
    } 
}; 

struct Mul { 
    template<typename T> static T apply(T l, T r) { 
     return l * r; 
    } 
}; 

template<typename Left, typename Right> 
Expression<Left, Mul, Right> operator*(const Left& l, const Right& r) { 
    return Expression<Left, Mul, Right>(l, r); 
} 

....................... 

// Class Vector extends std::array 
template<class T, size_t S> class Vector : public array<T, S> { 

public: 
    // Standard constructor 
    Vector<T, S>(array<T, S>&& a) : array<T, S>(a) {} 

    // Initializerlist constructor 
    Vector(const initializer_list<T>& data) { 
     size_t s = __min(data.size(), S); 
     auto it = data.begin(); 
     for (size_t i = 0; i < s; i++) 
      this->at(i) = *it++; 
    } 
}; 

..................................... 

int main { 

    Vector<double, 5> A({ 2, 3, 4, 5, 6 }); 
    Vector<double, 5> B({ 3, 3, 3, 3, 3 }); 
    Vector<double, 5> C; 
    C = A * B; // is a Vector: [6, 9, 12, 15, 18] and it works. 

    double d = A**B; // but this one does not work, the error message is: "no suitable conversion function from "Expression<Vector<double, 5U>, Mul, Vector<double, 5U> *>" to "double" exists" 

    cout << d << endl; // must give me: 60 
} 
+0

Sie tun es so: 'Punkt (A, B)'. Welche fehlgeleitete Seele bezeichnet das Skalarprodukt mit "**"? !!! –

+0

Ja, du hast Recht! aber das ist eine Hausaufgabe von der Schule :(muss es so sein !!! – KIA

+0

Sie müssen sagen, dass dies eine Hausaufgabe ist und dass Sie dies genau so umsetzen müssen, wie direkt in der Frage angegeben. –

Antwort

1

Sie können es auf diese Weise tun

#include <iostream> 
using namespace std; 

struct V 
{ 
    struct Vhelper 
    { 
    Vhelper(const V& v) : v(v) {} 
    const V& v; 
    }; 

    V operator*(const V&) const { 
    cout << "* called\n"; 
    return V(); 
    } 
    double operator*(const Vhelper&) const { 
    cout << "** called\n"; 
    return 42; 
    } 
    Vhelper operator*() { return Vhelper(*this); } 
}; 

int main() { 
    V a, b, c; 
    a = b * c; 
    double d = b ** c; 
    return 0; 
} 

aber Sie sollten vergessen, es ist immer Mög bling direkt nach der Arbeit. Tue dies niemals in echtem Code.

Dies ist kein vollwertiges operator**, weil es nicht in allen Kontexten ein echter ** Operator hätte verwendet werden können (und wenn Sie es für den Leistungsbetrieb verwendet werden soll, hat es falsch Rangfolge und Assoziativität) verwendet werden kann. Aber es sollte für ein kleines lustiges Lernprojekt in Ordnung sein.

+0

Machen Sie das nie wirklich in echtem Code. – Rotem

+0

danke !! :)) – KIA