Domanda

Ho una classe di intervallo generica e sto provando ad aggiungere un operatore di confronto in modo da poter verificare se un intervallo è uguale a un altro. Non riesce a compilare e non sono sicuro di come risolvere i problemi di cui si lamenta. Ho perso qualcosa di ovvio? Ecco uno snippet del codice:

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

... che non riesce a compilare con il seguente errore:

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

Devo definire le conversioni per ogni tipo che voglio sovraccaricare (sto usando un'istanza Int32)? Speravo di evitare quel genere di cose in quanto alquanto toglie l'uso di generici.

[Modifica] Ho un'istanza come segue:

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

... che si compila bene a parte i suddetti errori. Se converto ogni valore in un Int32, viene compilato, ma in realtà mi piacerebbe mantenere la classe il più generica possibile (ovvero non dover sovraccaricare per ogni tipo). Immagino di poter sottoclassare per ogni tipo e fare lì gli operatori sovraccarichi, ma la soluzione è meno accurata di quanto mi aspettassi quando ho scoperto generic s ;-)

È stato utile?

Soluzione

Non è possibile confrontare i valori di un tipo generico con un operatore == perché non tutti i tipi di valore sono garantiti per implementarlo.

Ad esempio, questo esempio di codice non riesce con errore " L'operatore '==' non può essere applicato agli operandi di tipo 'Test.MyStruct' e 'Test.MyStruct'.

struct MyStruct { }

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

Altri suggerimenti

In C ++ standard dovresti scrivere

template< class T >
class Range {

    bool operator==(Range const & rhs) const {
        return ( m_min == rhs.m_min ) && ( m_max == rhs.m_max );
    }
};

e funzionerebbe fintanto che il tipo T ha un operatore ==

Ma questo ovviamente non è C ++ standard, il generic, cosa il public ref class, il Range<T>%

Cerca alcune regole speciali per quanto riguarda <=> cose, immagino che mettano più vincoli sul tipo T rispetto a un modello standard.

Almeno in VS2005 è necessario:

generic<typename T> where T: IComparable, IEquatable<T>
public ref class Range {
    ...
};

Questo porta al compilatore ad accettare l'operatore ==. Non ho testato la classe Range, ma funziona come dovrebbe per il seguente metodo statico di una classe:

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

Per quanto ne so, puoi usare " Range " invece di " Range < T > " quando T è dello stesso tipo del tipo con cui viene creata un'istanza del modello di classe. Provalo.

Fuori tema, ma restituirei un valore costante e renderei costante anche quella funzione. Cambia anche protetto in privato a meno che tu non sappia che hai bisogno di protezione.

E presumo che '%' sia un refuso per '& amp;'? EDIT: tranne che ho appena notato il tag c ++ - cli, quindi è probabilmente un operatore pazzo presente in C ++ / CLI, che purtroppo non so nulla di :)

Hai provato ad aggiungere un where IComparable vincolo?

generic<typename T> where T: IComparable
public ref class Range  {
....
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top