Невозможно создать оператор == для универсального типа?

StackOverflow https://stackoverflow.com/questions/1443395

Вопрос

У меня есть общий класс диапазона, и я пытаюсь добавить оператор сравнения, чтобы я мог проверить, равен ли один диапазон другому. Он не компилируется, и я не уверен, как решить проблемы, на которые он жалуется. Я что-то упустил очевидное? Вот фрагмент кода:

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 );
    }
};

... который не компилируется со следующей ошибкой:

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

Нужно ли определять преобразования для каждого типа, который я хочу перегрузить (я использую экземпляр Int32)? Я надеялся избежать такого рода вещей, поскольку это скорее умаляет использование дженериков.

[Изменить] У меня есть следующие экземпляры:

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");
}

... который хорошо компилируется, кроме как из-за вышеупомянутых ошибок. Если я конвертирую каждое значение в Int32, оно компилируется, но на самом деле я бы хотел сохранить класс как можно более универсальным (т. Е. Не иметь перегрузок для каждого типа). Я думаю, я мог бы создавать подклассы для каждого типа и выполнять там перегруженные операторы, но решение оказалось менее изящным, чем я ожидал, когда впервые обнаружил generic s; -)

Это было полезно?

Решение

Вы не можете сравнивать значения универсального типа с оператором ==, потому что не все типы значений гарантированно реализуют его.

Например, этот пример кода завершается с ошибкой " оператор '==' нельзя применить к операндам типа 'Test.MyStruct' и 'Test.MyStruct'.

struct MyStruct { }

class Tester {
    void Go()
    {
        bool b = new MyStruct() == new MyStruct();
    }
 }

Другие советы

В стандартном C ++ вы написали бы

template< class T >
class Range {

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

и это будет работать, пока у типа T есть оператор ==

Но это, очевидно, не стандартный C ++, generic, вещь public ref class, Range<T>%

Посмотрите на некоторые специальные правила, касающиеся <=> вещей, я думаю, они накладывают больше ограничений на тип T, чем на стандартный шаблон.

По крайней мере, в VS2005 необходимо следующее:

generic<typename T> where T: IComparable, IEquatable<T>
public ref class Range {
    ...
};

Это приводит к тому, что компилятор принимает оператор ==. Я не тестировал класс Range, но он работает как следует для следующего статического метода класса:

generic <class K, class V> where V: IComparable, IEquatable<V>
static
K
KeyForValue(Collections::Generic::IDictionary<K,V>^ src, V value) {
    for each (Collections::Generic::KeyValuePair<K,V>^ kvp in src) {
        if (kvp->Value==value) return kvp->Key ;
    }
    throw gcnew Collections::Generic::KeyNotFoundException() ;
    return K() ;
}

Насколько я знаю, вы можете использовать " Range " вместо " Range < T > " когда T того же типа, что и тип, для которого создается шаблон класса. Попробуйте.

Не по теме, но я бы вернул const bool и сделал эту функцию тоже const. Также измените защищенный на частный, если вы не знаете, что вам нужен защищенный.

И я предполагаю, что «%» - это опечатка для «& amp;»? РЕДАКТИРОВАТЬ: за исключением того, что я только что заметил тег c ++ - cli, так что это, вероятно, какой-то сумасшедший оператор, присутствующий в C ++ / CLI, о котором, к сожалению, я ничего не знаю:)

Вы пытались добавить where IComparable ограничение?

generic<typename T> where T: IComparable
public ref class Range  {
....
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top