Search code examples
c++pointersiteratorcopying

C++: Convenient pointer array based value iterator for super-heavy objects


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.


Solution

  • Seems like a legitimate use case for 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 required