Frank
Frank

Reputation: 66244

How to avoid code duplication in this example?

I have two classes, Base and Derived. I provide a function that applies a function to all elements of Base, and another function to apply a function to all elements of Derived:

#include <iostream>
#include <vector>

class Base {
  typedef std::vector<int> Vec;
  typedef Vec::const_iterator CIter;
  CIter begin() const;
  CIter end() const;
};

class Derived : public Base {
  void add(int);
};


template<class F>
void processBase(const Base& b, F& f) {
  for (Base::CIter it = b.begin(); it != b.end(); ++it) {
    f(b, *it);
  }
}

template<class F>
void processDerived(Derived* d, F& f) {
  for (Base::CIter it = d->begin(); it != d->end(); ++it) {
    f(d, *it);
  }
}

How can I make the one function call the other, so that I don't have code duplication? (I gave only a minimal example; in my real code the for loops are kind of complicated, and that code is exactly repeated in the two functions.)

Do I have to template the processBase function? Or is there a way to use casting?

Upvotes: 1

Views: 126

Answers (1)

curiousguy
curiousguy

Reputation: 8318

Assuming the const Base& vs. Derived* difference is an error, yes, you need a function template to call the functor with the correct argument type:

template <typename Collection, typename F>
void processCollection (Collection& col, F& f) {
    for (typename Collection::CIter i=col.begin(); i!=col.end(); ++i) {
        f (col, *i);
    }
}

processCollection works on const or non-const, Base or Derived objects.

Upvotes: 5

Related Questions