Только не надо.
Многомерный массив - это не то место, где C ++ в лучшем виде.Здесь это все еще приемлемо, потому что N является постоянной времени компиляции, но если бы это была переменная времени выполнения, вы бы отключились, потому что VLA не поддерживаются в стандарте C ++ (даже если они поддерживаются как расширение реализации некоторыми реализациями, такими как gcc и clang).
Так что, если вам действительно нужно иметь дело с настоящими двумерными массивами, просто используйте пользовательский класс, содержащий базовый std::array
для фиксированного измерения времени компиляции или вектор для измерений времени выполнения дляобщий размер и предоставить 2d доступа к этому.Поскольку std::arrays
и векторы являются объектами, вы избегаете копирования и перемещения ресурсов (*).
Упрощенная реализация может быть такой:
class matrix {
std::vector<int> vec;
int rows;
int cols;
public:
matrix(int i, int j): rows(i), cols(j), vec(i * j) {}
int& at(int i, int j) {
return vec[j + i * cols];
}
const int& at(int i, int j) const {
return vec[j + i * cols];
}
};
Таким образом, базовая структура все ещеистинный 2D-массив, и у вас есть методы для его использования с двумя измерениями
Чего здесь еще не хватает:
- индексы и размеры, вероятно, должны быть
size_t
вместо int
- индексы могут быть проверены на допустимый диапазон в
at
методах - если вы их не проверяете, функция не должна вызываться at
... - otherконструкторы для построения матрицы поверх существующего двумерного массива (который может быть получен, например, из унаследованного кода C)
Дополнительное замечание:
Вы говорите, что хотите избежать векторов длявозможна многопоточность.Во-первых, я не могу себе представить, почему вектор был бы менее многопоточным, чем динамический массив, выделенный вручную.Во-вторых, если вам действительно нужно ручное выделение, вам нужно будет следовать правилу трех / пяти и реализовать собственные конструкторы копирования / перемещения и оператор присваивания в дополнение к пользовательскому деструктору.
(*) У меня естьпроект для написания универсального мульти-D контейнера, поддерживающего operator []
и итераторов, поэтому я знаю, что это довольно сложная задача.Я уже отправил предварительную версию для обзора кода , но она все еще далека от простого использования.