samedi 7 janvier 2017

How to avoid unnecessary construction of std::vector

I have two classes

class Base{ ... };

class Derived : public Base { ... };

and some other function which operates and modifies a collection of Base pointers:

void foo(std::vector<Base *> ptrs_to_base);

I have a std::vector<Derived> which holds my data. To pass it to foo I can construct a new vector of type std::vector<Base *> containing all pointers. In many situations this will be the easiest thing to do. However, I don't like the overhead with which it comes and in some situations it is simply not affordable to allocate dynamic memory.

Is there a way to change foo's interface as to do everything in place? In principle there should be no need for unnecessary construction of collections. I know there is no easy way, so usage of additional (multi-purpose) helper classes would be fine.

For example

template <typename Iter>
void foo(Iter begin, Iter end) {
   //*begin is of type Base*
   ...
}

std::vector<Derived> elements;
foo(elements.begin(), elements.end());

would be one solution which requires templates and doesn't make it obvious that only pointers of type Base * are required.

The following does not work as the iterator types are unrelated.

using Iter = std::vector<Base *>::iterator;
void foo(Iter begin, Iter end);

std::vector<Derived> elements;
foo(elements.begin(), elements.end()); // error! std::vector<Derived *>::iterator
                                       // can't be used for Iter

Aucun commentaire:

Enregistrer un commentaire