Operator overloading outside the template class with implicit conversions

I have a template class defined as

template<class T> class Wrap { /* ... */ public: Wrap(const T&); /* other implicit conversions */ /* ... */ }; 

I want to define all comparison operators for this class outside the class, like this

 template<typename T> bool operator == (const Wrap<T>&, const Wrap<T>&) { // Do comparison here } 

However, this declaration does not support implicit conversions of const T& or any other type to const Wrap<T>& .

So my question is how to make it support implicit conversions when one of the operands is of type Wrap<T> and the other is not. I do not want to write several declarations of each operator for each possible permutation.

+7
source share
2 answers
 template<class T> struct is_wrap : std::false_type {}; template<class T> struct is_wrap<Wrap<T>> : std::true_type {}; template<class T1, class T2> typename std::enable_if<is_wrap<typename std::common_type<T1, T2>::type>::value, bool>::type operator == (const T1& t1, const T2& t2) { const typename std::common_type<T1, T2>::type& tc1 = t1, tc2 = t2; // compare with tc1 and tc2 } 
+4
source

Someone else will formulate this better, but I think the problem is that the compiler cannot output T to Wrap<T> without passing the Wrap object to it. I think your situation should be resolved if you explicitly give the operator== argument of the template: operator==<int>(7, 4) , for example, should work.

I don't have a compiler in front of me, but here's my attempt:

 template<typename T> typename std::enable_if<std::is_convertible<Wrap<T>, T>::value, bool>::type operator==(const Wrap<T>& l, const T& r) { return l.stuff == Wrap<T>(r).stuff; } template<typename T> typename std::enable_if<std::is_convertible<Wrap<T>, T>::value, bool>::type operator==(const T& l, const Wrap<T>& r) { return r == l; // call above operator } 

This should work if both sides are Wrap and the other side is not. You can also do both sides as const T& , however if Wrap really implicitly built from any T , you can use your operator== for many unintended comparisons, even int s, string s, etc.

+1
source

All Articles