2017-12-17 5 views
-2

std :: arrayを拡張する汎用クラスVectorと、Vectorの可能な式を定義する汎用クラスExpressionがあります。C++で独自の演算子を作成しますか?

例:

ベクトルA({1,2,3});

ベクトルB({2,2,2});

と式:

A + B。

A * B;

A - B;

A/B;

2つのベクトルAとBのスカラー生成としてdoubleを返すこの式A ** Bが必要です。結果は2 + 4 + 6 = 12でなければなりません。問題は演算子**の実装です!

この演算子はどのように記述できますか?**

私の考えは、ポインタを返した後、構造体・ムルオーデル乗算演算子をオーバーロードベクトルの間接参照演算子*をオーバーロードすることです* ...このエラーは解決することができませんでした:

「いいえ、適切な変換関数からの"式< ...>" "ダブル"」

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

あなたは 'dot(A、B)'のようにします。どの誤った魂が '**'でスカラー製品を表しているのですか? –

+0

ええ、そうですよ!これは学校からの宿題です(それはそうでなければなりません)。 – KIA

+0

これは宿題であり、質問に直接述べたとおりに正確にこれを実装しなければならないことを伝える必要があります。 –

答えて

1

が存在するためにあなたは、このよう

#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; 
} 

それを行うことができますが、それが今までpossiだ忘れる必要がありますあなたの仕事が採点された直後に。実際のコードでこれをしないでください。

実際には**オペレータが使用されている可能性があります(電源操作に使用する場合は、優先順位と結合性が間違っています)。しかし、少し楽しい学習プロジェクトのためにはOKです。

+0

実際のコードでこれを絶対にしないでください – Rotem

+0

ありがとう!! :)) – KIA