In my code, I have something like this:
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());
}
What I'd really want is something like this:
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
is allowed to copy the objects, so there's no scope problem. Inside doSomething
is the only place where I'd like copying to take place, because these objects really are very slow to copy (I've profiled and it's a chokepoint).
At the same time, I don't want to change the signature of doSomething
to accept iterators that dereference SuperHeavyObject*
, because that would require a lot of changes; dereferencing to SuperHeavyObject
would be ideal, as it would only happen at one place (where copying happens).
My question is; I could write an iterator like this myself, but it feels like I'm reinventing the wheel. Does C++ (11) have facilities to do this? I also have Boost if someone knows of anything like this.
Seems like a legitimate use case for std::reference_wrapper
1:
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());
}