Скажем, у меня есть функция, которая берет начальный и конечный итераторы из 2D-контейнера.
Вот первая проблема. В опубликованном фрагменте есть такие строки:
int arr[2][3] = {{0, 1, 2}, {3, 4, 5}};
func(arr, arr + 2 * 3);
// ^^^^^^^
Хотя arr
обычно называют многомерным или двумерным массивом, на самом деле это массив из 2 массивов из 3 целых чисел. Его размер не 6 (= 2x3), но 2.
Если вы хотите использовать два итератора в сигнатуре функции, вы можете переписать ваш забавный c следующим образом:
// This would print out the elements
template <typename RandomIt>
void func(RandomIt first, RandomIt last)
{
// Iterates through the rows
for (auto row = first; row < last; ++row)
{
// Loops through each row
for (auto const& el : *row)
{
std::cout << ' ' << el;
}
std::cout << '\n';
}
}
int main()
{
int arr[2][3] = {{0, 1, 2}, {3, 4, 5}};
func(std::cbegin(arr), std::cend(arr));
std::cout << '\n';
std::vector<std::vector<int>> b {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}};
func(b.cbegin(), b.cend());
}
Я хотел бы получить размеры контейнера
Есть несколько способов сделать это sh.
Если вы ограничивая себя простыми массивами, вы можете просто изменить сигнатуру функции и использовать правильные аргументы шаблона и передать массив по ссылке:
template <class T, std::size_t Rows, std::size_t Cols>
void func(T const (&arr)[Rows][Cols]) { /* ... */ }
Стандартная библиотека предлагает различные бесплатные функции, которые могут помочь в написании более общих слов. такие функции, как std::size
.
template <class M>
void func(M const& m)
{
for (size_t i{}; i < std::size(m); ++i)
{
for (size_t j{}; j < std::size(m[i]); ++j)
{
std::cout << ' ' << m[i][j];
}
std::cout << '\n';
}
}
В общем, вы можете создать свой собственный класс, моделирующий 2D-контейнер, и методы записи, возвращающие правильное количество строк или столбцов.