Pregunta

Tengo una clase de rango genérico y estoy tratando de agregar un operador de comparación para poder probar si un rango es igual a otro. No se compila y no estoy seguro de cómo solucionar los problemas de los que se queja. ¿Me he perdido algo obvio? Aquí hay un fragmento del código:

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

... que no se compila con el siguiente error:

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

¿Necesito definir conversiones para cada tipo que quiero sobrecargar (estoy usando una instanciación Int32)? Tenía la esperanza de evitar ese tipo de cosas, ya que más bien le quita el uso de genéricos.

[Editar] Tengo una instanciación de la siguiente manera:

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

... que compila bien aparte de los errores antes mencionados. Si convierto cada valor en un Int32, se compila, pero realmente me gustaría mantener la clase lo más genérica posible (es decir, no tener que sobrecargarla para todos y cada uno de los tipos). Creo que podría subclasificar para cada tipo y hacer los operadores sobrecargados allí, pero la solución es menos clara de lo que esperaba cuando descubrí generic s ;-)

¿Fue útil?

Solución

No puede comparar valores de un tipo genérico con un operador == porque no se garantiza que todos los tipos de valores lo implementen.

Por ejemplo, este ejemplo de código falla con el error " El operador '==' no se puede aplicar a los operandos de tipo 'Test.MyStruct' y 'Test.MyStruct'.

struct MyStruct { }

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

Otros consejos

En C ++ estándar escribirías

template< class T >
class Range {

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

y funcionaría siempre que el tipo T tenga un operador ==

Pero esto obviamente no es C ++ estándar, lo generic, lo public ref class, lo Range<T>%

Busque algunas reglas especiales con respecto a <=> cosas, supongo que imponen más restricciones al tipo T que una plantilla estándar.

Al menos en VS2005, lo que se necesita es:

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

Esto lleva al compilador a aceptar el operador ==. No probé la clase Range, pero funciona como debería para el siguiente método estático de una clase:

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

Hasta donde yo sé, puede usar " Range " en lugar de " Range < T > " cuando T es del mismo tipo que el tipo con el que se instancia la plantilla de clase. Pruébalo.

Fuera de tema, pero devolvería un const bool y haría que esa función también sea constante. También cambie protegido a privado a menos que sepa que necesita protección.

¿Y supongo que '%' es un error tipográfico para '& amp;'? EDITAR: excepto que acabo de notar la etiqueta c ++ - cli, por lo que probablemente sea un operador loco presente en C ++ / CLI, que lamentablemente no sé nada sobre :)

¿Has intentado agregar una restricción where IComparable?

generic<typename T> where T: IComparable
public ref class Range  {
....
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top