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! ]