У меня есть функция, которая собирает и объединяет некоторое количество векторов (конечно, с одинаковыми типами элементов). Вот основная идея этого:
vector<A> combined;
...
for(int i = 0; i < someNumber; i++)
combined.insert(combined.end(), GetNextRange().begin(), GetNextRange().end());
Все это сделано для того, чтобы я мог последовательно перебирать объединенный набор. Я хотел бы достичь этого без всего копирующего бизнеса.
Поскольку GetNextRange () на самом деле возвращает ссылку на следующий вектор в строке, как я могу использовать этот факт и собрать ссылки вместе / выстроить их в линию для желаемого метода доступа?
Во-первых, если GetNextRange()
на самом деле, действительно возвращает следующий вектор, ваше использование GetNextRange()
дважды, чтобы получить begin()
и end()
не принесет вам много пользы. По крайней мере, вам нужно сделать что-то вроде
for (int i = 0; i != someNumber; ++i) {
std::vector<A> const& tmp(GetNextRange());
combined.insert(combined.end(), tmp.begin(), tmp.end());
}
Если вы хотите сделать это несколько лучше, вы можете создать собственный итератор, который внутренне хранит текущий вектор, индекс и текущую позицию. Вероятно, это будет входной итератор, фактически сохраняющий текущую информацию в подходящей общей записи, чтобы ее можно было скопировать.
Вот простая (и не проверенная) реализация:
class joined_iterator {
struct record {
record(int limit)
: index(0)
, limit(limit)
, current(limit? &GetNextRange(): 0)
, pos()
{
if (this->current) {
this->current->begin();
}
}
int index;
int limit;
std::vector<A> const* current;
std::vector<A>::const_iterator pos;
};
std::shared_ptr<record> ptr;
public:
joined_iterator(int limit): ptr(std::make_shared<record>(limit)) {}
bool operator== (joined_iterator const& other) const {
return this->ptr->current
? bool(other.ptr->current)
: !bool(other.ptr->current);
}
bool operator!= (joined_iterator const& other) const {
return !(*this == other);
}
A const& operator*() const { return *this->ptr->pos; }
A const* operator->() const { return &*this->ptr->pos; }
joined_iterator& operator++() {
if (++this->ptr->pos == this->ptr->current->end()) {
if (++this->ptr->index == this->ptr->limit) {
this->ptr->current = 0;
}
else {
this->ptr->current = &GetNextRange();
this->ptr->pos = this->ptr->current->begin();
}
}
return *this;
}
joined_iterator operator++(int) {
joined_iterator rc(*this);
this->operator++();
return rc;
}
};
Других решений пока нет …