Здесь, на rsdn много раз обсуждались многомерные массивы (представлять как одномерные и проч.), но я среди обсуждений не нашёл именно того, что мне нужно.
Необходимо сделать объект — оболочку для массивов, для удобства работы с массивами. (Проблема стара как мир

)
Т.е. обычным на С++ выглядит следующее:
{
//Размерность первая
const unsigned int s1 = 4;
//Размерность вторая
const unsigned int s2 = 8;
//Временный массив для передачи данных функции
int **arr = new int*[s1];
for(unsigned int i=0; i<s1; i++)
arr[i] = new int[s2];
//Заполняем массив
for(unsigned int i=0; i<s1; i++)
for(unsigned int j=0; j<s2; j++)
d[i][j] = <какое-то значение>;
//Вызываем некий метод некого объекта(это всё не важно, главное что ему
//требуется указатель на указатель, являющийся массивом целых чисел)
//прототипа навроде такого: setAD2(int** a, unsgined int size1, unsigned int size2)
fv.setAD2(arr, s1, s2);
//Метод забрал часть данных из двухмерного массива в своё внутренее хранилище,
//о котором мы ничего не знаем и знать не хотим, массив нам больше не нужен
//Освобождаем память
for(unsigned int i=0; i<s1; i++)
delete[] arr[i];
delete[] arr;
}
Утомляет всё это писать, хочется написать выделение и освобождение памяти раз и навсегда (

для всех массивов), чтобы можно было так:
{
//Объявили массив и выделили память
Array<int> a(10);
//Заполняем массив
for(unsigned int i=0; i<a.size(); i++)
d[i] = <какое-то значение>;
//Вызвали функцию требующу указатель на инт, являющийся массивом и размер массива
funcAr(a.getPoint(), a.size());
//Деструктор вызовется автоматически и
//беспокоится о не освобождении памяти не нужно
}
Это легко реализовать с помощью вот такого шаблона (привожу очень упрощенный вид):
template <typename type> class A
{
private:
type *arr;
public:
A() : arr(0) {};
A(int x) {arr = new type[x];};
type& opertor [] (int index) {return arr[index];};
};
Однако в таком случае
для n-мерного массива (в примере ниже n=2) потребуется опять таки выделять память для каждого измерения:
{
A<A<int> > ob1(10); //Получается память будет выделена только под одно измерение, как выделить под другое?
a[3][8] = 5; //ошибка, обращаемся к памяти по "левому" адресу
//Возможно сделать некий метод класса А под названием getMem, выделяющий память и вызывать его так:
for(unsigned int i=0; i<ob1.getSize(); i++)
ob1[i].getMem(10);
a[3][8] = 5;
//всё отлично, память выделена
assert(a[3][8] == 5);
}
Решение рабочее, но не красивое — уж лучше вообще без объектов, просто int** и ему выделять память.
Тогда пришла идея сделать
шаблон с параметром, вот такой:
template <typename type, unsigned int size> class A
{
private:
type *arr;
public:
A() : {arr = new type[size];};
type& opertor [] (int index) {return arr[index];};
};
Тогда
код (1)
{
A<A<int, 10>, 10> ob1;
a[3][8] = 5; //всё отлично, память выделена
}
...работает. Но не более.
Дальше
начинаются извращения, например
чтобы присваивать (кажется логичным массиву из 10 целочисленных элементов присвоить массив из 9 целочисленных элементов, просто скопировав 9 значений)
надо делать приведение типов. Что-то типа такого (привожу упрощенный вариант):
template <size_t len2, typename U> Arr<T, len> & operator= (Arr<U, len2> & arr2)
{
for (int j = 0; j < len2; ++j)
arr[j] = arr2[j];
return *this;
}
Да и вообще в
коде (1) мы уже
не имеем возможности создавать как таковые динамические массивы, параметру шаблона нужно передавать константу. И функции, требующей на входе двумерный массив,
не понятно нак передавать его, если он хранится в виде A<A<int, 10>, 10>, получается одномерный массив объектов (одномерных массивов целых чисел) — это не то что нам нужно.
Итак. Я хочу создать некий пользовательский тип(класс), который позволит работать вот так (примерно так):
{
Array<Array<int>> a; //Здесь каким-то образом задаю обе размерности
a[7][5] = 5;
std::cout << a[7][5] << endl;
Array<Array<int>> b; //Другого размера, нежели a
b = a; //Копирует значения (те которые поместятся, т.к. размер может быть и меньше)
b.reSize(50); //Перевыделяет память и копирует значения
a.newSize(100); //Освобождает занятую память и выделяет новый блок под сто элементов
Array<Array<int>> c(b); //Конструктор копирования, если у c и b разные мерности,
//то хочется чтобы такой код был определён как ошибачный на стадии компиляции
//И главная цель - вызов функции с прототипом похожим на вот такой func(int** a, int s1, int s2),
//каким-нибудь простым способом, например таким:
func(a.getPoint(), a.size(), a[0].size());
}
Спасибо большое всем кто прочитал и что-то придумал.
Ещё раз (кратко), я хочу:
Создать объект — многомерный массив. Он должен:
1. выделять память, освобождать память, не утруждая этим клиентский код;
2. иметь возможность его использования там где требуется int** (на месте инта — любой тип, на месте двух
звёздочек — любое количество звёздочек (равное мерности массива));
3. уметь менять свой размер по требованию, уже после создания (т.е. что-то типа reSize, newSize описанных
выше);
4. использовать конструкторы копирования, перегруженные операторы присваивания для массивов однинаковой
мерности и типа, но разных размерностей.
Помогите, поделитесь, пожалуйста, любыми
мыслями (отсылать меня использовать готовые библиотеки не нужно, посылать совсем далеко то же),
советами, как реализовать эти 4 пункта!
Искал, то что хочу не нашёл. В std есть valarry, но 2 пункт (а для него всё это и делалось) не удет с ними работать, да и 4 прийдётся переписать самому. Перечитал главу про шаблоны у Б. Страуструпа, прочитал про шаблоны у Р. Лафоре, листал А. Александреску (жёстко написано, не дорос я ещё до него).
Заранее огромное спасибо всем, кто хоть что-то напишет, прочитав моё сообщение!
(Я уже давно е...сь с этой идеей. (е...сь — еграюсь

))