Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Comparison operator overload via base classes.

14 views
Skip to first unread message

usenet only_tech_talk

unread,
Mar 16, 2010, 12:28:43 AM3/16/10
to
Hello,

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

Daniel Krügler

unread,
Mar 16, 2010, 6:45:51 AM3/16/10
to
On 16 Mrz., 05:28, usenet only_tech_talk <usenet.tech.t...@gmail.com>
wrote:

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

Alf P. Steinbach

unread,
Mar 16, 2010, 8:48:23 PM3/16/10
to
* usenet only_tech_talk:


<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

Nick Hounsome

unread,
Mar 17, 2010, 12:47:20 PM3/17/10
to
On 16 Mar, 04:28, usenet only_tech_talk <usenet.tech.t...@gmail.com>
wrote:

> Hello,
>
> 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&){}

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.

0 new messages