Невозможно создать оператор == для универсального типа?
-
22-07-2019 - |
Вопрос
У меня есть общий класс диапазона, и я пытаюсь добавить оператор сравнения, чтобы я мог проверить, равен ли один диапазон другому. Он не компилируется, и я не уверен, как решить проблемы, на которые он жалуется. Я что-то упустил очевидное? Вот фрагмент кода:
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 {
....