Всем привет, столкнулся со следующей проблемой: когда я создаю двумерный массив вида int a[n][n], Visual Studio 2022 выдаёт ошибку компиляции: "выражение не является константой", где выражение это n (n я предварительно ввожу через cin>>n;). Как можно решить данную проблему? Было бы славно решить её созданием двумерного вектора через библиотеку , так как привычно работать именно через неё.
Машина тебе правильно говорит, $$$n$$$ не является константой.
Я понимаю, а как тогда создать двумерный массив размера n*m, где n и m вводятся? Приходится задачи на двумерные массивы писать в онлайн компиляторах потому что они не жалуются на такое
Возможность объявлять массивы динамического размера называется VLA (variable length array) и является очень спорной возможностью языка C из стандарта C99. Она не входит в стандарт C++, однако некоторые компиляторы типа GCC включают в себя расширения, которые позволяют пользоваться ею и в С++. Именно поэтому на онлайн компиляторах, где зачастую по умолчанию предлагается GCC, такой код работает, а вот в VisualStudio c компилятором MSVC — нет.
Я бы не рекомендовал полагаться на VLA вообще, т. к. компилятор идет на довольно сильные ухищрения маскируя VLA под обычный массив с константным размером, но как только вещи станут чуть сложнее, он просто откажется это делать.
StackOverflow: Почему VLA не входит в стандарт С++?
Как с этим жить?
Если максимальное $$$N$$$ известно заранее, то можно создать массив достаточно большого размера, чтобы любое меньшее $$$N$$$ гарантированно в него помещалось.
Если размеры неизвестны или нельзя выделить памяти по максимуму на все измерения, то можно использовать многомерный вектор. Однако это повлечет потерю некоторую производительности, т. к. каждая строка будет отдельным куском в памяти
чтобы память была одним последовательным куском можно использовать vector на
n*m
элементов и использовать индексы видаi*m + j
. Чтобы это не резало глаза, можно написать функцию обертку, оформить 2D массив как класс с перегрузкой операторов или использоватьstd::mdspan
Добавлю, что можно не писать вектор-вектор-вектор-вектор-тип-тип, компилятор может сам это вывести:
Для одно- и двумерного вектора это не сильно увеличивает удобность, но для трёхмерного случая уже заметно:
Спасибо