Please consider :
struct A{};
template<typename T> struct B{};
struct C : B< C >{};
struct D : B< D >{};
template<typename T,typename R>
bool operator==(const B<T>&,const R&){}
template<typename T,typename L>
bool operator==(const L&,const B<T>&){}
One would hope this is all that is needed:
int main (int argc, char * const argv[]) {
A a; C c1,c2; D d1,d2;
c1 == a;
c1 == c2;
c1 == d2;
d1 == d2;
d2 == d1;
return 0;
}
but of course not (ambiguous overload). So in a second round of naive
hope, one tries:
template<typename T,typename T1>
bool operator==(const B<T>&,const B<T1>&){}
before accepting the ugly truth:
bool operator==(const C&,const C&){}
bool operator==(const D&,const D&){}
bool operator==(const C&,const D&){}
bool operator==(const D&,const C&){}
Is this the end of the road, or is there something more scalable?
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
I believe it should be possible to go with three overloads:
template<class T>
struct IsBaseOfB {
static const bool value = std::is_base_of<B<T>, T>::value;
};
// Use std::is_base_of from <type_traits> if your compiler
// provides that or use boost::is_base_of otherwise.
template<typename L, typename R>
typename std::enable_if<IsBaseOfB<L>::value && !IsBaseOfB<R>::value,
bool>::type
operator==(const L&, const R&){ return true; }
template<typename L, typename R>
typename std::enable_if<!IsBaseOfB<L>::value && IsBaseOfB<R>::value,
bool>::type
operator==(const L&, const R&){ return true; }
template<typename L, typename R>
typename std::enable_if<IsBaseOfB<L>::value && IsBaseOfB<R>::value,
bool>::type
operator==(const L&, const R&){ return true; }
HTH & Greetings from Bremen,
Daniel Krügler
<code>
#include <stdio.h>
void say( char const s[] ) { printf( "%s\n", s ); }
struct A{};
template< typename T > struct B{};
struct C: B< C >{};
struct D: B< D >{};
template< typename T, typename T1 >
void operator==( B< T > const&, B< T1 > const& ) { say( "BB" ); }
template< typename T >
void operator==( A const&, B< T > const& ) { say( "AB" ); }
template< typename T >
void operator==( B< T > const& b, A const& a )
{ return (a == b); }
int main()
{
A a; C c1,c2; D d1,d2;
c1 == a; // AB
c1 == c2; // BB
c1 == d2; // BB
d1 == d2; // BB
d2 == d1; // BB
}
</code>
Cheers & hth.,
- Alf
Assuming that you actually provided an implementation here what would
it mean????
This purports to compare a B<T> to an arbitrary class.
> template<typename T,typename L>
> bool operator==(const L&,const B<T>&){}
>
> One would hope this is all that is needed:
>
> int main (int argc, char * const argv[]) {
>
> A a; C c1,c2; D d1,d2;
> c1 == a;
I don't see how you could ever expect this to work since a and c1 are
totaly unrelated.
> c1 == c2;
> c1 == d2;
I don't see how you could ever expect this to work since d2 and c1 are
totaly unrelated.
There is no relationship between two different instantiations of the
same template.
> d1 == d2;
> d2 == d1;
>
> return 0;
>
> }
The one that might make sense to me (given your use of B and assuming
no unwanted conversions) is
template<typename T>
bool operator==(const B<T>&,const T&);
template<typename T>
bool operator==(const T&, const B<T>&);
Of course on another level many would argue that a == b should be
false whenever typeof(a) != typeof(b).
Whenever this does make sense it is usually the case that one can be
converted to the other and hence no asymetric equality operator is
required.