Один вопрос: вы когда-нибудь слышали о концепции View
.
Идея состоит в том, что вместо фактического перемещения данных вы просто создаете «представление» (шаблон Proxy), которое будет ограничивать / изменятьваше восприятие этого.
Например, для диапазона очень простой реализацией будет:
template <typename Iterator>
struct Range
{
Iterator mBegin, mEnd;
};
Boost.Range
предлагает толстую версию со множеством вещей.
Преимущества в этом случае многочисленны.среди которых:
- Один
vector
, что обеспечивает лучшую локальность памяти - Разделение простое и не требует перемещения / копирования данных
Вот split
с этим методом:
typedef Range<std::vector<int>::iterator> range_type;
std::vector<range_type> split(std::vector<int> const& range, size_t x)
{
std::vector<range_type> subRanges;
for (std::vector<int>::iterator it = range.begin(), end = range.end();
it != end; it += std::min(x, (size_t)std::distance(it,end)))
{
subRanges.push_back(range_type(it,end));
}
return subRanges;
}
Конечно, это работает, только если вы можете держать объект range
вокруг.
ОтносительноВаш оригинальный алгоритм: использование цикла while
является ложным и заставляет вас использовать гораздо больше move
s, чем необходимо.Созданная мной петля for
должна быть намного лучше в этом отношении.