Я работал над шаблонной функцией с нетиповыми параметрами (чтобы избежать динамического размещения массивов), когда возник ряд вопросов. Мой первый вопрос касается назначения переменных во время компиляции. Это произошло из-за следующих попыток вызова функции шаблона:
template<int n>
int *getDegrees(int A[][n]) {
//return degrees
}
int main(int argc, char **argv) {
int n = 10;
int A[n][n];
int *degs = getDegrees<n>(A);
}
Здесь у нас есть две ошибки: во-первых, компилятор не может разрешить вызов getDegrees(A)
:
main.cc:27: error: no matching function for call to ‘getDegrees(int [(((long unsigned int)(((long int)n) + -0x00000000000000001)) + 1)][(((long unsigned int)(((long int)n) + -0x00000000000000001)) + 1)])’
Во-вторых, мы не можем использовать n
в вызове шаблона, так как это не постоянное выражение. Просто делая n
константа решает проблемы
const int n = 10;
однако, если бы я должен был сделать
int m = 10;
const int n = m;
мы получаем те же ошибки. Хотя второе присваивание может быть разрешено компилятором, считается ли это плохой формой для этого? Кроме того, зачем делать n
постоянная разница в разрешении вызова функции?
Мой другой вопрос касается vlas: выделена ли для них память в стеке или куче (и зависит ли это от компилятора)? Похоже, были некоторые противоречия даже в том, чтобы разрешить их в C ++, следует ли их избегать в пользу векторов (или подобных контейнеров)?
Цени любое понимание!
Я постараюсь ответить на все, что смогу получить от вашего вопроса.
Вы можете изменить прототип функции для получения массива по ссылке:
template<size_t n> // see the type
int *getDegrees(int (&A)[n][n]) { // see the signature
// ...
}
В приведенном выше коде мы используем тот факт, что массив имеет одинаковые размеры.
Однако в общем случае это должно быть:
template<size_t n1, size_t n2> // see the type
int *getDegrees(int (&A)[n1][n2]) { // see the signature
// ...
}
Если размер слишком велик, то компилятор выдаст сообщение об ошибке. например (из g ++):
ошибка: размер массива «A» слишком велик
Теперь перейдем к другому вопросу, касающемуся разницы между присваиванием постоянного целого числа.
В C ++ размер массива должен быть постоянным времени компиляции и
const int n = 10;
выполняет это требование. Поскольку компилятор может разобрать это, 10 — это буквальное число, присваиваемое n
,
В случае,
int m = 10;
const int n = m;
Компилятор узнает, что источник n
является не сама константа времени компиляции. И, таким образом, это делает код плохо сформированным.
Других решений пока нет …