A vector<vector<int> >
(обратите внимание на пробел в > >
) может работать хорошо, но это не обязательно самый эффективный способ сделать что-то. Другой способ, который может работать довольно хорошо, - это обертка вокруг одного вектора, которая отслеживает «форму» представляемой матрицы и предоставляет функцию или перегруженный оператор для доступа к данным:
template <class T>
class matrix {
int columns_;
std::vector<T> data;
public:
matrix(int columns, int rows) : columns_(columns), data(columns*rows) {}
T &operator()(int column, int row) { return data[row*columns_+column]; }
};
Обратите внимание, что стандарт C ++ позволяет operator[]
принимать только один операнд, поэтому вы не можете использовать его для этой работы, по крайней мере, напрямую. В приведенном выше примере я (очевидно, достаточно) вместо этого использовал operator()
, поэтому подписки выглядят больше как Fortran или BASIC, чем вы привыкли в C ++. Если вы действительно используете нотацию []
, вы можете сделать это в любом случае, хотя это немного сложнее (вы перегружаете его в классе матрицы для возврата прокси, а затем прокси-класс также перегружает operator[]
для возврата (a ссылка на) правильный элемент - он внутренне слегка уродлив, но в любом случае работает отлично).
Редактировать: Так как я лежу без дела, вот пример того, как реализовать последнее. Я написал это (довольно давно), прежде чем большинство компиляторов включили std::vector
, поэтому он статически выделяет массив вместо использования вектора. Это также для случая с 3D (так что задействованы два уровня прокси), но, если повезет, основная идея все равно дойдет до конца:
template<class T, int size>
class matrix3 {
T data[size][size][size];
friend class proxy;
friend class proxy2;
class proxy {
matrix3 &m_;
int index1_, index2_;
public:
proxy(matrix3 &m, int i1, int i2)
: m_(m), index1_(i1), index2_(i2)
{}
T &operator[](int index3) {
return m_.data[index1_][index2_][index3];
}
};
class proxy2 {
matrix3 &m_;
int index_;
public:
proxy2(matrix3 &m, int d) : m_(m), index_(d) { }
proxy operator[](int index2) {
return proxy(m_, index_, index2);
}
};
public:
proxy2 operator[](int index) {
return proxy2(*this, index);
}
};
Используя это, вы можете обращаться к массиву с обычным синтаксисом C ++, например:
matrix3<double, size> m;
for (int x=0; x<size; x++)
for (int y = 0; y<size; y++)
for (int z = 0; z<size; z++)
m[x][y][z] = x*100 + y * 10 + z;