Функция, о которой вы спрашиваете (где размеры известны только во время выполнения), является нестандартным расширением C++, но стандартным для C.99 (сделанным в необязательной функции в C.11). Эта функция называется variable-length array (VLA), а ссылка - документация для GCC.
Если вы используете GCC, то вы должны передать длину массива в качестве параметра функции.
void foo (int m, int arr[][m]) {
//...
}
Однако, кажется, есть ошибка в любом компиляторе или документации, как указано выше функция синтаксиса прототип работает только при компиляции кода C, а не C++ (как НКУ версии 4.8.2). Единственная работа вокруг я нашел использовать параметр void *
и брось его ИНТ тело функции:
int foo_workaround (int m, void *x)
{
int (*arr)[m] = static_cast<int (*)[m]>(x);
//...
}
Есть и другие решения, если вы не хотите, чтобы полагаться на расширение компилятора. Если вы не против отдельного выделения для каждой строки, вы можете использовать вектор векторов, например:
std::vector<std::vector<int> > arr(n, std::vector<int>(m));
Однако, если вы хотите один блок распределения, как вы продемонстрировали в своем собственном примере, то лучше создать класс-оболочку около vector
, чтобы дать вам синтаксис типа 2-d.
template <typename T>
class vector2d {
int n_;
int m_;
std::vector<T> vec_;
template <typename I>
class vector2d_ref {
typedef std::iterator_traits<I> TRAITS;
typedef typename TRAITS::value_type R_TYPE;
template <typename> friend class vector2d;
I p_;
vector2d_ref (I p) : p_(p) {}
public:
R_TYPE & operator [] (int j) { return *(p_+j); }
};
typedef std::vector<T> VEC;
typedef vector2d_ref<typename VEC::iterator> REF;
typedef vector2d_ref<typename VEC::const_iterator> CREF;
template <typename I>
vector2d_ref<I> ref (I p, int i) { return p + (i * m_); }
public:
vector2d (int n, int m) : n_(n), m_(m), vec_(n*m) {}
REF operator [] (int i) { return ref(vec_.begin(), i); }
CREF operator [] (int i) const { return ref(vec_.begin(), i); }
};
обертка в operator[]
возвращает промежуточный объект, который также перегружает operator[]
, чтобы позволить 2-мерный массив синтаксиса при использовании оболочки.
vector2d<int> v(n, m);
v[i][j] = 7;
std::cout << v[i][j] << '\n';
1. Нет. 2. Имеет ли значение, если ответ на 1. "нет"? – juanchopanza
Это нестандартное поведение (и вы можете изменить параметры компилятора, чтобы запретить нестандартное поведение).Сделайте то, что вы делаете с вектором, но просто завершите его в классе. – chris
Или используйте 'vector>' –
matsjoyce