I have the following class definition:
template <typename T>
class MyBox {
public:
MyBox(T value) { _value = value; }
operator T() const { return _value; }
private:
T _value;
};
typedef MyBox<int> MyInt;
typedef MyBox<std::string> MyString;
When I try to use operators on my typedefs like this
bool first = MyInt(1) == MyInt(1); // works
bool second = std::string(MyString("a")) == std::string(MyString("a")); //works
bool third = MyString("a") == MyString("a"); // does not compile
the compiler complains about the third comparison
no operator "==" matches these operands. operand types are: MyString == MyString
and this happens with any other non-primitve boxing (e.g. MyBox<float> works but MyBox<std::map<int,int> > not. Why is that so?
This is especially unclear to me because for the first and second comparison the operator T() is used - why can't that be done automatically for MyString as well?
UPDATE: Is there a simple solution to this other than providing the specific operators for each non-primitive template? And what to do with MyString("a") == std::string("a")?
The reasons on why it works for built-in types, but does't work for custom types is answered in the following SO quesiton: using user-defined conversions with implicit conversions in comparisons. In short, this is because type conversion does not happen for template-deduced types. And while built-in operator== for int is not a template (and thus can be found using type conversion when MyBox<int> is used), operator== for std::string is a template.
However, the question mentioned above doesn't have details on how to solve this problem. Here is how: add following free functions
template<class T>
bool operator==(const MyBox<T>& lhs, const MyBox<T>& rhs) {
return static_cast<const T&>(lhs) == static_cast<const T&>(rhs);
}
template<class T>
bool operator==(const MyBox<T>& lhs, const T& rhs) {
return static_cast<const T&>(lhs) == rhs;
}
template<class T>
bool operator==(const T& lhs, const MyBox<T>& rhs) {
return lhs == static_cast<const T&>(rhs);
}
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