Если ваш многомерный вектор является фактическим многомерным вектором, например что-то вроде std::vector<std::vector<int>>
, что не рекомендуется, то вам придется написать свой собственный итератор. Это не очень сложно. Boost.Iterator имеет концепции, которые могут помочь в его реализации.
Если ваш многомерный вектор представляет собой один вектор, размер которого установлен на произведение размеров (то есть ширина * высота), что является предпочтительным способом обработки этого, тогда это гораздо проще. Это можно сделать с помощью утилит, предоставляемых Boost.Range.
Вот быстрый и грязный пример использования Boost.Range. Это можно сделать немного красивее с decltype
. Если ваш компилятор не поддерживает C ++ 11 (в частности, auto
), я бы не советовал использовать это, потому что код становится очень трудно читать.
template<typename T>
boost::iterator_range<typename T::iterator>
GetRow(T& vec, typename T::size_type row, typename T::size_type w,
typename T::size_type h) {
return boost::make_iterator_range(
vec.begin() + (row * w),
vec.begin() + ((row + 1) * w)
);
}
template<typename T>
boost::strided_range<boost::iterator_range<typename T::iterator>>
GetColumn(T& vec, typename T::size_type col, typename T::size_type w,
typename T::size_type h) {
boost::iterator_range<typename T::iterator> range = boost::make_iterator_range(
vec.begin() + col,
vec.begin() + col + (h - 1) * w + 1
);
return boost::strided_range<boost::iterator_range<typename T::iterator>>(w, range);
}
И затем использовать эти функции довольно просто, хотя, опять же, это может стать очень уродливым, если ваш компилятор не поддерживает auto
.
const size_t WIDTH = 3;
const size_t HEIGHT = 3;
std::vector<int> vec(WIDTH * HEIGHT);
// Fill the first row with 1.
auto row = GetRow(vec, 0, WIDTH, HEIGHT);
for (auto it = row.begin(); it != row.end(); ++it) {
(*it) = 1;
}
// Fill the second column with 2.
auto col = GetColumn(vec, 1, WIDTH, HEIGHT);
for (auto it = col.begin(); it != col.end(); ++it) {
(*it) = 2;
}
// Contents of vec is:
// 1 2 1
// 0 2 0
// 0 2 0
Возможно, вы также захотите взглянуть на Boost.MultiArray, библиотеку, предназначенную для таких вещей. Он предоставляет необходимую вам функциональность, но это определенно не самая дружелюбная библиотека.