@Drottarutarnum
Любопытный любитель

Как передать двумерный массив в функцию без динамического выделения памяти?

Есть двумерный массив, его второй уровень может быть от 0 до 10, а первый неограничен
Сейчас сделано так:
template<typename dataType, size_t dataSize>
size_t GetSize(dataType(&)[dataSize]) { 
	return dataSize; 
}


struct ArrayData {
	int data[10];
	int size;
};


void foo(ArrayData *data, size_t size) {
	for (size_t i = 0; i < size; i++) {
		std::cout << i << ": ";

		for (size_t i2 = 0; i2 < data[i].size; i2++) {
			std::cout << data[i].data[i2] << ", ";
		}

		std::cout << std::endl;
	}
}



int main() {
	ArrayData test[] = {
		{{1, 2, 3}, 3},
		{{1, 2, 3, 4, 5}, 5},
		{{1}, 1},
	};

	foo(test, GetSize(test));

	std::system("pause");
}


Очень неудобно задавать каждому массиву количество элементов, сейчас я сделал это для тестирования, но потом их станет очень много

Можно ли как-то возложить на компилятор эту работу? Или другой способ? Хотелось бы просто писать как-то так:
ArrayData test[] = {
		{1, 2, 3},
		{1, 2, 3, 4, 5},
		{1}
	};
  • Вопрос задан
  • 312 просмотров
Решения вопроса 1
@Mercury13
Программист на «си с крестами» и не только
Для неизменяемых данных я придумал.
#include <iostream>

template <class T>
struct Array
{
    const size_t size;
    const T* const data;

    const T* begin() const { return data; }
    const T* end() const { return data + size; }

    constexpr Array(const std::initializer_list<T>& x)
        : size(x.size()), data(x.begin()) {}
};

using Row = Array<int>;
using Matrix = Array<Row>;

Matrix mtx = {
  {1, 2, 3 },
  { 10, 20, 30, 40, 50 },
  {},
  { 100 }
};

int main()
{
    for (auto& u : mtx) {
        for (auto& v : u) {
            std::cout << v << ' ';
        }
        std::cout << std::endl;
    }
    return 0;
}


Для изменяемых данных пока вышло только так.
#include <iostream>

// Изменяемый вариант
template <class T>
struct Array2
{
    const size_t size;
    T* const data;

    T* begin() { return data; }
    T* end() { return data + size; }
    const T* begin() const { return data; }
    const T* end() const { return data + size; }
    T& operator[](int i) { return data[i]; }

    template <size_t N>
    constexpr Array2(T (&x)[N])
        : size(N), data(x) {}
};

using Row2 = Array2<int>;
using Matrix2 = Array2<Row2>;

int main()
{
    int i;
    std::cin >> i;

    int row1[] = { 1, i, 3 };
    int row2[] = { 10, 2*i, 30, 3*i, 50 };
    int row3[] = { 13 };
    int row4[] = { 100 };

    Row2 mtx[] = { row1, row2, row3, row4 };

    mtx[1][4] = i * 6;

    for (auto& u : mtx) {
        for (auto& v : u) {
            std::cout << v << ' ';
        }
        std::cout << std::endl;
    }
    return 0;
}
Ответ написан
Пригласить эксперта
Ответы на вопрос 3
@res2001
Developer, ex-admin
Можно ли как-то возложить на компилятор эту работу?

int arr[] = {1, 2, 3};
size_t size = sizeof(arr)/sizeof(arr[0]);  // size == 3

Но как вы это прикрутите к вашей схеме не знаю.
Возможно есть смысл определить ваши массивы как константы по одному и использовать эти константы для инициализации test и вычисления sizeof().
Ответ написан
@vanyamba-electronics
Нужно просто освоить std::vector:
#include <vector>

using namespace std;

void foo(vector<ArrayData>& data)
{
    for (vector<ArrayData>::iterator it = data.begin(); it != data.end(); ++it)
        cout << it->data[0] << " ";
    cout << endl;
}

int main() {
   vector<ArrayData> test;
   ArrayData data0 = {{1, 2, 3}, 3};

   test.push_back(data0);
   foo(test);
}
Ответ написан
vt4a2h
@vt4a2h Куратор тега C++
Senior software engineer (C++/Qt/boost)
Да есть. В C++ есть стандартная библиотека, в которой есть некоторые структуры данных:
#include <vector>

template <class T>
using Matrix = std::vector<std::vector<T>>;

// ... 

template <class T>
void print(const Matrix<T> &matrix)
{
    for (auto &&r : matrix) {
        for (auto &&e : r) {
            std::cout << e << " ";
        }
        std::cout << std::endl;
    }
} 

// ...

Matrix<int> m = {
    {1, 2, 3},
    {5, 6, 7, 8},
    {9, 10}
}

print(m);


Вот тут можно прочитать о классе vector: https://en.cppreference.com/w/cpp/container/vector

PS
Я это всё не компилировал, но как-то так в общем должно работать.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы