Хороший псевдоним типа ol:
using pairlist = std::initializer_list<std::pair<int,int>>;
for(auto pair : pairlist{{1,2}, {3,4}})
{
// stuff happens here
}
Чтобы вернуть указатель на ваш массив элемента массива, нужен тип int (*)[5]
, а не int **
:
class Myclass {
private:
int myarray[5][5];
public:
int (*get_array())[5];
};
int (*Myclass::get_array())[5] {
return myarray;
}
Существует два возможных типа, которые вы можете вернуть, чтобы обеспечить доступ к вашему внутреннему массиву. Старый стиль C будет возвращать int *[5]
, так как массив легко распадается на указатель на первый элемент, который имеет тип int[5]
.
int (*foo())[5] {
static int array[5][5] = {};
return array;
}
Теперь вы также можете вернуть правильная ссылка на внутренний массив, простейший синтаксис - через typedef:
typedef int (&array5x5)[5][5];
array5x5 foo() {
static int array[5][5] = {};
return array;
}
Или немного более громоздко без typedef:
int (&foo())[5][5] {
static int array[5][5] = {};
return array;
}
Преимущество C ++ что фактический тип поддерживается, а это означает, что фактический размер массива известен со стороны абонентов.
Как вернуть многомерный массив, скрытый в частном поле?
blockquote>Если он должен быть скрыт, зачем вы его возвращаете в первую очередь?
В любом случае вы не можете возвращать массивы из функций, но вы можете вернуть указатель на первый элемент. Что такое первый элемент массива 5x5 из ints? Массив из 5 целых чисел, конечно:
int (*get_grid())[5] { return grid; }
В качестве альтернативы вы можете вернуть весь массив по ссылке:
int (&get_grid())[5][5] { return grid; }
... добро пожаловать в синтаксис адватора C; -)
Могу я предложить вместо
std::vector<std::vector<int> >
илиboost::multi_array<int, 2>
?
Измените ваш int на int [] [] или попробуйте использовать int [,] вместо этого?
Мне удалось заставить эту функцию работать в C ++ 0x, используя автоматический вывод типа. Однако я не могу заставить это работать без этого. Родные C массивы не очень хорошо поддерживаются в C ++ - их синтаксис чрезвычайно отвратителен. Вы должны использовать класс-оболочку.
template<typename T, int firstdim, int seconddim> class TwoDimensionalArray {
T data[firstdim][seconddim];
public:
T*& operator[](int index) {
return data[index];
}
const T*& operator[](int index) const {
return data[index];
}
};
class Myclass {
public:
typedef TwoDimensionalArray<int, 5, 5> arraytype;
private:
arraytype myarray;
public:
arraytype& get_array() {
return myarray;
}
};
int main(int argc, char **argv) {
Myclass m;
Myclass::arraytype& var = m.get_array();
int& someint = var[0][0];
}
Этот код компилируется просто отлично. Вы можете получить предварительно написанный класс-оболочку внутри Boost (boost :: array), который поддерживает весь shebang.
int **Myclass::get_array() {
return (int**)myarray;
}
Двумерный массив не распадается на указатель на указатель на int. Он распадается на указатель на массивы ints - то есть только первое измерение распадается на указатель. Указатель не указывает на int указатели, которые при инкрементах увеличиваются на размер указателя, но на массивы из 5 целых чисел.
class Myclass {
private:
int myarray[5][5];
public:
typedef int (*pointer_to_arrays)[5]; //typedefs can make things more readable with such awkward types
pointer_to_arrays get_array() {return myarray;}
};
int main()
{
Myclass o;
int (*a)[5] = o.get_array();
//or
Myclass::pointer_to_arrays b = o.get_array();
}
Указатель на указатель (int**
) используется, когда каждый subarray выделяется отдельно (т. е. изначально у вас есть массив указателей)
int* p[5];
for (int i = 0; i != 5; ++i) {
p[i] = new int[5];
}
Здесь мы имеем массив из пяти указателей, каждый из которых указывает на первый элемент в отдельном блоке памяти, всего 6 различных блоков памяти.
В двумерном массиве вы получаете единый непрерывный блок памяти:
int arr[5][5]; //a single block of 5 * 5 * sizeof(int) bytes
Вы должны видеть, что расположение памяти этих вещей совершенно иное, и поэтому эти вещи не могут быть возвращены и переданы одинаково.