我有一个通用范围类,我正在尝试添加一个比较运算符,以便我可以测试一个范围是否等于另一个范围。它无法编译,我不知道如何解决它抱怨的问题。我错过了明显的东西吗?以下是代码片段:
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
时,解决方案不如我预期的那样整洁; - )
答案 0 :(得分:1)
您无法将泛型类型的值与==运算符进行比较,因为并非所有值类型都可以保证实现它。
例如,此代码示例失败,错误“Operator'=='无法应用于'Test.MyStruct'和'Test.MyStruct'类型的操作数。
struct MyStruct { }
class Tester {
void Go()
{
bool b = new MyStruct() == new MyStruct();
}
}
答案 1 :(得分:1)
在标准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施加比标准模板更多的约束。
答案 2 :(得分:1)
至少在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() ;
}
答案 3 :(得分:0)
据我所知,您可以使用“范围”而不是“范围&lt; T&gt;”当T与类模板实例化的类型相同时。试一试。
偏离主题,但我会返回一个const bool,并将该函数设为const。除非您知道需要保护,否则还要将protected更改为private。
我认为'%'是'&amp;'的拼写错误?编辑:除了我刚刚注意到c ++ - cli标签,所以这可能是C ++ / CLI中的一些疯狂操作符,遗憾的是我对此一无所知:)
答案 4 :(得分:0)
您是否尝试过添加where IComparable
约束?
generic<typename T> where T: IComparable
public ref class Range {
....