I have a class template that needs to be able to compare between two objects, via comparison objects derived from a Compare
class I have:
template<typename T>
class Container {
public:
template<typename A, typename B>
class Compare {
public:
virtual bool eq(const A&, const B&) const = 0;
};
I provide a default comparison objects, assuming type T
has the operator ==
:
template<typename A, typename B>
class Default : public Compare<A,B> {
public:
bool eq(const A& a, const B& b) const { return a==b; }
};
private:
Compare<T,T>* comparison_object;
bool uses_default;
Container() : comparison_object(new Default<T,T>()), uses_default(true) {}
Container(Compare<T,T>& cmp) : comparison_object(&cmp), uses_default(false) {}
~Container() { if(uses_default) delete comparison_object; }
};
However, when I try to compile this with a custom class that does not have an operator==
overload (even if I provide an object derived from Compare
):
MyObjCmp moc;
Container<MyObj>(&moc);
The compiler complains that the operator doesn't exist:
error: no match for 'operator==' (operand types are 'const MyObj' and 'const MyObj')
This makes sense, because the Default
class still needs to be created, even though I don't need it. But now I need a workaround...
Any ideas?
Rather than a run-time check for a null pointer, you could use a compile-time check for no object:
Container() : comparison_object(new Default<T,T>), uses_default(true) {}
Container(Compare<T,T>& cmp) : comparison_object(&cmp), uses_default(false) {}
The default constructor, and hence Default
, will only be instantiated if needed, so there's no error when using the non-default constructor with a type for which Default
would fail.
But be careful juggling raw pointers like that, it's a recipe for memory leaks and worse. Don't forget the virtual destructor for Compare
and the Rule of Three, and be very careful that a non-default comparator doesn't get unexpectedly destroyed. Better still, use a smart pointer to take care of all that for you.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With