2009-09-18 40 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() ; 
}