вектор и матрица, основанная на std: vector - PullRequest
0 голосов
/ 01 июля 2019

Я пытаюсь унаследовать от std :: vector для создания небольших полезных классов для обработки математического вектора и матриц.

После некоторой работы это набросок того, что я получил до сих пор:

#include <vector>
template<typename T>
struct vec : public std::vector<T> {
    using std::vector<T>::vector;   // to inherit the constructors
    vec(const std::vector<T> &v) :std::vector<T>(v) {}
    //vec() :std::vector<T>() {}    // it is needed?  
    vec &operator+=(const std::vector<T> &B) {
        auto ib = B.begin();
        for (auto i = this->begin(); i != this->end(); ++i, ++ib) {
            *i += *ib;
        }
        return *this;
    }
    friend vec operator+(vec a, const vec &b) { return std::move(a += b); }
};

template<typename T>
struct matr : public vec<vec<T>>
{
    using vec<vec<T>>::vec; // to inherit the constructors
    matr transpose() const {
        matr res(this->operator[](0).size(), vec<T>(this->size()));
        for (size_t i = 0; i < res.size(); ++i)
            for (size_t j = 0; j < res[0].size(); ++j)
                res[i][j] = this->operator[](j)[i];
        return std::move(res);
    }
    //matr(const std::vector<std::vector<T>> &M):vec<std::vector<T>>(M){}
    T operator()(size_t i, size_t j) const {
        return this->operator[](j)[i];
    }
    T &operator()(size_t i, size_t j){
        return this->operator[](j)[i];
    }
};

using namespace std;
int main() {
    vec<int> W1 = { 1,2,3 };             // ok only if vec inherits constructors from vector
    vector<int> W2 = { 1,2,3 };          // ok
    vec<int> W3 = W2;                    // ok but I had to define a constructor in vec from vector
    vec<vec<int>> M1 = { W1,W2 };        // ok only if vec inherits constructors from vector and explicit cast
    vector<vector<int>> M2 = { W1,W2 };  // ok!
    vector<vec<int>> M3 = { W1,W2 };     // ok!
    matr<int> M3b = { W1,W2 };           // ok!
    matr<int> M4 = { {1,2,3},{4,5,6},{7,8,9} }; // ok only if vec inherits constructors from vector
    //vector<vector<int>> M5 = M4;       // KO it works if matr is declared also public vector<vector<int>>
    matr<int> M6 = M4+M4;                // Ok but only if vec defines it's own constructor ¿?. 
                                         // Shouldn't matr inherit the operator+ from vec in any case?
    matr<int> M7 = M1;                   // Ok but I had to define a explicit cast in vec
    //matr<int> M8 = M2;                 // KO no idea
    matr<int> M9 = M3;                   // Ok if v
    matr<int> M10 = M9.transpose();      // Ok (std::move works)
    vec<int> a = M10[2];                 // OK but there are problems if multiple inheritance 
    int b = M10(1, 2);                   // OK    idem
    M10(1, 2) = 4;                       // OK    idem
    // b = M10[1,2];                     // KO no idea as how to define it. 
}

Мой главный вопрос о том, как заставить работать линии, определяющие М5 и М8, не мешая другим. M5 компилируется, если matr наследуется как от vec<T>, так и от vector<vector<T>>, но тогда у меня много проблем с неоднозначностью. Для M8 я безуспешно пытался создать конструктор в matr, когда я раскомментировал его, некоторые другие строки перестали работать (по крайней мере, M3b и M4).

Я использую C ++ для программирования некоторых задач и алгоритмов всякий раз, когда мне это нужно, но у меня очень мало опыта в занятиях, и я не профессиональный программист, поэтому извините, если это глупо вопрос. Я использую VC ++ 2017 или G ++ 8.2 с --std = gnu ++ 14, и я всегда пытаюсь скомпилировать оба.

...