C ++: удобный итератор значений на основе массива указателей для сверхтяжелых объектов

В моем коде у меня есть что-то вроде этого:

vector<SuperHeavyObject> objects; // objects in this vector are extremely slow to copy!
for (auto &objectGroup : objectGroups) {
vector<SuperHeavyObject> objectsInThisGroup;
for (size_t index : objectGroup) {
objectsInThisGroup.push_back(objects[index]); // slow as copying is needed!
}
doSomething(objectsInThisGroup.begin(), objectsInThisGroup.end());
}

То, что я действительно хочу, это что-то вроде этого:

vector<SuperHeavyObject> objects; // objects in this vector are extremely slow to copy!
for (auto &objectGroup : objectGroups) {
vector<SuperHeavyObject*> objectsInThisGroup; // pointers!
for (size_t index : objectGroup) {
objectsInThisGroup.push_back(&objects[index]); // not slow anymore
}
doSomething(magicIterator(objectsInThisGroup.begin()),
magicIterator(objectsInThisGroup.end()));
}

doSomething разрешено копировать объекты, поэтому проблем с областью видимости нет. внутри doSomething это единственное место, где я хотел бы, чтобы происходило копирование, потому что эти объекты на самом деле очень медленно копируются (я профилировал, и это дроссельная точка).

В то же время я не хочу менять подпись doSomething принимать итераторы разыменования SuperHeavyObject*потому что это потребует много изменений; разыменование SuperHeavyObject было бы идеально, так как это произошло бы только в одном месте (где происходит копирование).

Мой вопрос Я мог бы написать такой же итератор, но мне кажется, что я заново изобретаю колесо. Есть ли в C ++ (11) возможности для этого? У меня также есть Boost, если кто-то знает что-нибудь подобное.

0

Решение

Похоже, законный вариант использования для std::reference_wrapper1:

vector<SuperHeavyObject> objects;
for (auto &objectGroup : objectGroups) {
vector<std::reference_wrapper<SuperHeavyObject>> objectsInThisGroup;
for (size_t index : objectGroup) {
// fast, we are only storing reference-like objects
objectsInThisGroup.push_back(objects[index]);
}
doSomething(objectsInThisGroup.begin(), objectsInThisGroup.end());
}

  1. C ++ 11 требуется
2

Другие решения

Спасибо @ matteo-italia за ваш полезный ответ! Я использовал его некоторое время, и решил присмотреться к итераторам Boost, и обнаружил, что у них есть indirect_iterator что также является хорошим способом сделать то, что я хочу.

«irect_iterator адаптирует итератор, применяя дополнительную разыменование внутри оператора * () »

http://www.boost.org/doc/libs/1_59_0/libs/iterator/doc/indirect_iterator.html

1

По вопросам рекламы [email protected]