Re: Abstract base class as template parameter (for std::set comparator)
On 22 Feb., 22:16, "Aaron J. M." <ajm...@ns.sympatico.ca> wrote:
I'm creating std::set objects with my own comparators. My comparators
are in following hierarchy, rooted at the abstract base class
BaseCompare:
class BaseCompare
{
virtual bool operator()(const SomeOtherClass &lhs, const
SomeOtherClass &rhs) const = 0;
};
Don't forget the virtual destructor!
[..]
I want to dynamically set what comparator is used when I create a
set. I want to be able to do something like this:
void something(BaseCompare &compareRef)
{
std::set<SomeOtherClass, BaseCompare> aSet(compareRef);
...
}
Here I'd pass either an ACompare or a BCompare. Unfortunately, my
compiler complains about BaseCompare's virtual function. Is there a
way to fix this?
The compiler warn's you rightly because of the slicing effect.
You comparison object must be at least copy constructible (if not
assignable). The solution is a simple non-polymorphic wrapper class
(i.e. a variant of the bridge pattern):
class BaseCompareWrapper
{
public:
explicit BaseCompareWrapper(const BaseCompare& cmp) : pcmp(&cmp)
{}
bool operator()(const SomeOtherClass &lhs, const
SomeOtherClass &rhs) const
{
return (*pcmp)(lhs, rhs);
}
private:
const BaseCompare* pcmp;
};
Now do this:
void something(const BaseCompare &compareRef)
{
std::set<SomeOtherClass, BaseCompareWrapper>
aSet(BaseCompareWrapper(compareRef));
...
}
Greetings from Bremen,
Daniel Kr?gler
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]