Невозможно создать оператор == для универсального типа? - PullRequest
0 голосов
/ 18 сентября 2009

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

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

Ответы [ 5 ]

1 голос
/ 16 июня 2011

По крайней мере, в 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() ;
}
1 голос
/ 18 сентября 2009

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

Например, этот пример кода завершается с ошибкой «Оператор» == не может быть применен к операндам типа «Test.MyStruct» и «Test.MyStruct».

struct MyStruct { }

class Tester {
    void Go()
    {
        bool b = new MyStruct() == new MyStruct();
    }
 }
1 голос
/ 18 сентября 2009

В стандартном 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>%

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

0 голосов
/ 18 сентября 2009

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

generic<typename T> where T: IComparable
public ref class Range  {
....
0 голосов
/ 18 сентября 2009

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

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

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

...