Я хочу сделать что-то вроде:
const int N = 10;
void foo (const int count)
{
int (* pA) [N][count] = reinterpret_cast<int(*)[N][count]>(new int[N * count]);
...
}
Но мой компилятор (VS2010) не хочет этого делать:
ошибка C2057: ожидаемое постоянное выражение
ошибка C2540: непостоянное выражение в виде границы массива
Таким образом, он выражает свое недовольство count
,
Я знаю, как это можно обойти, реализовав немного по-другому. Но я просто не понимаю, Зачем С ++ запрещает мне использовать этот путь. Я понимаю, почему C ++ должен знать размер массивов в стеке во время компиляции (чтобы выделить память массива). Но почему такие же ограничения необходимы в отношении указатели к массиву (в конце концов, указатель — это просто инструмент для работы с выделенной памятью)?
Ну, на самом деле то, что вы хотите, в принципе хорошо, но вы используете неправильный синтаксис.
Все измерения, кроме первого, должны быть константами времени компиляции, потому что они используются в арифметике указателей. Первый может быть разным во время выполнения. Это работает:
int (* pA)[N] = new int[count][N];
Помните, что массив совместим с указателем на элемент-тип, и подписка на них работает одинаково. Поэтому, когда у вас выделен двумерный массив (массив массивов), вы должны хранить указатель на одномерный массив.
Там нет никакого способа сделать int[N][count]
тем не менее, потому что для этого потребуется массив элементов (подмассивов) переменного размера.
Кроме того, обратите внимание, что N
это константа-выражение, но count
не является. Хотя они оба имеют одинаковый тип, count
это параметр, определенный во время выполнения.
Если вы хотите принять константное интегральное выражение в качестве аргумента, сделайте его аргументом шаблона:
template <int count>
void foo()
Сейчас count
это постоянное выражение так же, как N
,