views:

166

answers:

4

I've got a generic range class and I'm trying to add a comparison operator so I can test whether one range is equal to another. It fails to compile and I'm not sure how to fix the issues it's complaining about. Have I missed something obvious? Here's a snippet of the code:

generic<typename T>
public ref class Range
{
protected:
    T m_min;
    T m_max;
public:

    ...
    ...

    bool operator==(Range<T>% rhs) 
    {
  return ( m_min == rhs.m_min ) && ( m_max == rhs.m_max );
    }
};

...which fails to compile with the following error:

1>c:\projects\Utils.h(47) : error C2676: binary '==' : 'T' does not define this operator or a conversion to a type acceptable to the predefined operator

Do I need to define conversions for each type that I want to overload (I'm using an Int32 instantiation)? I was hoping to avoid that sort of thing as it rather detracts from using generics.

[Edit] I've got an instantiation as follows:

Range<Int32> a = Range<Int32>(0,5);
Range<Int32> b = Range<Int32>(1,3);

if( Int32(2) != Int32(4) )
{
 printf("Int32 supports != operator");
}

if( a != b )
{
 printf("A != B : SUCCESS");
}
else
{
 printf("A == B : FAIL");
}

...which compiles okay aside fromt he aforementioned errors. If I convert each value to an Int32 it compiles, but really I'd like to keep the class as generic as possible (i.e. not havnig to overload for each and every type). I guess I could subclass for each type and do the overloaded operators there, but the solution is less neat than I had expected when I first discovered generics ;-)

A: 

As far as I know, you can use "Range" instead of "Range<T>" when T is the same type as the type the class template is instantiated with. Give that a try.

Off-topic, but I'd return a const bool, and make that function const too. Also change protected to private unless you know you need protected.

And I assume that '%' is a typo for '&'? EDIT: except I just noticed the c++-cli tag, so that's probably some crazy operator present in C++/CLI, which sadly I know nothing about :)

Ben Hymers
Fair points on the const's and private. Yes you're right about the C++/CLI craziness ;-)
Jon Cage
+1  A: 

You cannot compare values of a generic type with an == operator because not all value types are guaranteed to implement it.

For example, this code sample fails with error "Operator '==' cannot be applied to operands of type 'Test.MyStruct' and 'Test.MyStruct'.

struct MyStruct { }

class Tester {
    void Go()
    {
        bool b = new MyStruct() == new MyStruct();
    }
 }
Igor ostrovsky
+1  A: 

In standard C++ you would write

template< class T >
class Range {

    bool operator==(Range const & rhs) const {
        return ( m_min == rhs.m_min ) && ( m_max == rhs.m_max );
    }
};

and it would work as long as the type T has an operator==

But this is obviously not standard C++, the generic, thing the public ref class, the Range<T>%

Look for some special rules regarding generic things, I would guess they put more constrains on the type T than a standard template.

Pieter
Yeah, that's what I was hoping to do, but it seems generics are more restricted than I'd hoped (or I've not found the appropriate way of achieving the same thing).
Jon Cage
A: 

Have you tried adding a where IComparable constraint?

generic<typename T> where T: IComparable
public ref class Range  {
....
tragomaskhalos
Just tried that and got the same error
Jon Cage