Question

J'ai une classe de plage générique et j'essaie d'ajouter un opérateur de comparaison afin de pouvoir vérifier si une plage est égale à une autre. Il ne parvient pas à compiler et je ne sais pas comment résoudre les problèmes pour lesquels il se plaint. Ai-je oublié quelque chose d'évident? Voici un extrait du code:

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

... qui ne compile pas avec l'erreur suivante:

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

Dois-je définir des conversions pour chaque type que je souhaite surcharger (j'utilise une instanciation Int32)? J'espérais éviter ce genre de chose, car cela empêche l'utilisation de médicaments génériques.

[Modifier] j'ai une instanciation comme suit:

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

... qui compile bien à part les erreurs susmentionnées. Si je convertis chaque valeur en un Int32, il compile, mais j'aimerais vraiment garder la classe aussi générique que possible (c'est-à-dire ne pas avoir à surcharger pour chaque type). Je suppose que je pourrais sous-classer pour chaque type et utiliser les opérateurs surchargés, mais la solution est moins élégante que ce à quoi je m'attendais lorsque j'ai découvert generic s; -)

Était-ce utile?

La solution

Vous ne pouvez pas comparer les valeurs d'un type générique avec un opérateur == car tous les types de valeurs ne sont pas forcément implémentés.

Par exemple, cet exemple de code échoue avec l'erreur & "L'opérateur" == "ne peut pas être appliqué aux opérandes de type" Test.MyStruct "et" Test.MyStruct ".

struct MyStruct { }

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

Autres conseils

En C ++ standard, vous écririez

template< class T >
class Range {

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

et cela fonctionnerait tant que le type T a un opérateur ==

Mais ce n’est évidemment pas le C ++ standard, le generic, le public ref class, le Range<T>%

Recherchez des règles spéciales concernant <=> certaines choses. Je suppose qu'elles imposent plus de contraintes au type T qu'un modèle standard.

Dans VS2005 au moins, il faut:

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

Ceci amène le compilateur à accepter l'opérateur ==. Je n'ai pas testé la classe Range, mais cela fonctionne normalement pour la méthode statique suivante d'une 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() ;
}

Pour autant que je sache, vous pouvez utiliser & "Range &"; au lieu de " Range < T > " lorsque T est du même type que le type avec lequel le modèle de classe est instancié. Essayez-le.

Hors sujet, mais je retournerais un const bool et rendrais cette fonction const aussi. Également changer protégé en privé, sauf si vous savez que vous avez besoin d’être protégé.

Et je suppose que '%' est une faute de frappe pour '& amp;'? EDIT: sauf que je viens de remarquer la balise c ++ - cli, donc c’est probablement un opérateur fou présent dans C ++ / CLI, dont malheureusement je ne connais rien:)

Avez-vous essayé d'ajouter une where IComparable contrainte?

generic<typename T> where T: IComparable
public ref class Range  {
....
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top