2009-09-18 39 views
0

我有一个通用的范围类,我试图添加一个比较运算符,所以我可以测试一个范围是否等于另一个。它无法编译,我不知道如何解决它所抱怨的问题。我错过了明显的东西吗?这里的代码片段:无法为泛型类型创建运算符==?

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 

我需要定义,我想重载每个类型转换(I”使用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"); 
} 

...这编译好的一边fromt他上述错误:

[编辑]如下我有一个实例。如果我将每个值转换为Int32编译,但实际上我想尽可能保持类的通用性(即不要为每种类型重载)。我想我可以分类为每种类型,并做那里的超载运营商,但解决方案是不太整洁比我预期当我第一次发现generic s ;-)

+0

您有一个类的实例,其中T用实际类型替换 - 该类型是否具有一个==运算符? – sharptooth 2009-09-18 09:19:49

回答

1

因为不能将泛型类型的值与==运算符进行比较,并非所有值类型都保证实现它。

例如,此代码示例失败,错误“操作员‘==’不能被应用于类型‘Test.MyStruct’和‘Test.MyStruct’的操作数。

struct MyStruct { } 

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

据我所知,你可以使用“范围”而不是“范围<T>”,当T与类模板实例化的类型相同时。试试看。

离题,但我会返回一个const布尔,并使该函数也是const。除非你知道你需要保护,否则更改保护为私人。

我假设'%'是'&'的拼写错误?编辑:除了我只注意到C++ - cli标记,所以这可能是一些疯狂的操作符存在于C++/CLI中,遗憾的是我对此一无所知:)

+0

关于const和private的公平点。是的,你是对的C + +/CLI的疯狂;-) – 2009-09-18 09:34:27

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 classRange<T>%

寻找一些关于generic事情的特殊规则,我猜想他们对类型T的限制比标准模板更多。

+0

是的,这就是我希望做的,但它似乎泛型比我所希望的更受限制(或者我还没有找到适当的方式来实现一样)。 – 2009-09-18 09:43:47

0

您是否尝试添加where IComparable约束?

generic<typename T> where T: IComparable 
public ref class Range { 
.... 
+0

刚刚尝试过,得到了同样的错误 – 2009-09-18 13:39:21

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