Pergunta

Eu tenho uma classe gama genérica e eu estou tentando adicionar um operador de comparação para que eu possa testar se um intervalo é igual a outro. Ela não consegue compilar e eu não tenho certeza de como corrigir os problemas que está reclamando. Eu perdi algo óbvio? Aqui está um trecho do 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 não consegue compilar com o seguinte erro:

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

Eu preciso definir conversões para cada tipo que eu quero sobrecarga (estou usando uma instanciação Int32)? Eu estava esperando para evitar esse tipo de coisa, pois em vez diminui usando os genéricos.

[Edit] Eu tenho uma instanciação da seguinte forma:

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 bem além fromt ele erros acima mencionados. Se eu converter cada valor para um Int32 ele compila, mas realmente eu gostaria de manter a classe mais genérica possível (ou seja, não havnig à sobrecarga para cada tipo). Eu acho que eu poderia subclasse para cada tipo e fazer os operadores sobrecarregados lá, mas a solução é menos puro do que eu esperava quando eu descoberto pela primeira vez generics; -)

Foi útil?

Solução

Você não pode comparar valores de um tipo genérico com um operador == porque nem todos os tipos de valor são garantidos para implementá-lo.

Por exemplo, este exemplo de código falha com o erro "Operator '==' não pode ser aplicado a operandos do tipo 'Test.MyStruct' e 'Test.MyStruct'.

struct MyStruct { }

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

Outras dicas

Em C ++ padrão que iria escrever

template< class T >
class Range {

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

e ele iria trabalhar, desde que o tipo T tem um operador ==

Mas este não é, obviamente, padrão C ++, o generic, coisa que o public ref class, o Range<T>%

Procure algumas regras especiais sobre coisas generic, eu acho que eles colocar mais restrições no tipo T do que um modelo padrão.

No VS2005, pelo menos, o que é necessário é:

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

Isto leva a que o compilador aceitar o == operador. Eu não testar a classe Range, mas funciona como deveria para o seguinte método estático de uma 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() ;
}

Tanto quanto eu sei, você pode usar "Range" em vez de "Range " quando T é do mesmo tipo que o tipo do modelo de classe é instanciado com. Dar um que tente.

Off-topic, mas eu retornar um bool const, e fazer essa função const também. Também mude protegida como privado, a menos que você sabe que precisa protegido.

E eu supor que '%' é um erro de digitação para 'e'? EDIT: só que eu só notei o c ++ - cli tag, de modo que é provavelmente algum operador louco presente em C ++ / CLI, o que, infelizmente, eu não sei nada sobre:)

Você tentou adicionar uma restrição where IComparable?

generic<typename T> where T: IComparable
public ref class Range  {
....
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top