Я реализую класс n-мерного массива, который представляет собой шаблон следующим образом (обратите внимание, что данные хранятся в линейном массиве, длина которого является произведением всех измерений):
template< class valType, int rank >
class NDimensionalArray
{
public:
private:
valType* m_data;
int* m_dimensions;
int m_rank;
};
Таким образом, идея заключается в том, что пользователь (я) может указать массив ранга 2 и определенного размера, то есть:
NDimensionalArray<double,2> matrix(10,10);
Теперь сложность заключается в том, чтобы специализировать конструкторы для 1-> n измерений, каждый конструктор принимает n параметров, где n - ранг массива. Теперь я подумал об использовании типа valarray, который используется в printf (), однако с этим определяем одномерный массив с двумя измерениями, то есть:
NDimensionalArray<double,1> matrix(10,10);
было бы вполне приемлемым поведением. Есть ли какая-то хитрая уловка, которую я могу использовать, чтобы компилятор делал повторения? Реально, пока я знаю ранг и длину каждого измерения, конструктор может быть общим:
{
int nElements = m_dimensions[0];
for ( int i=1 ; i<m_rank ; ++i )
nElements *= m_dimensions[i];
m_data = new valType[nElements];
}
Редактировать: Обратите внимание, что аналогичная операция будет необходима для методов доступа.
Также я рассмотрел вариант конструктора, который выглядит следующим образом:
NDimensionalArray( const NDimensionalArray<int,1>& dimensions );
Что можно использовать как:
NDimensionalArray<int,1> dimVec(2); // Need a specification for 1-dimensional arrays.
dimVec(0) = 10;
dimVec(1) = 10;
NDimensionalArray<double,2> matrix(dimVec);
Это было бы жизнеспособным решением, но оно уродливо по сравнению с использованием, которое я хотел бы. Также доступ к многомерным массивам стал бы серьезной болью и очень медленным созданием вектора измерения для каждого доступа.