Я пытаюсь унаследовать от 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, и я всегда пытаюсь скомпилировать оба.