Reputation: 66244
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
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