2011-08-18 5 views
9

decir que tenía la clase/estructura Foo¿Sería esta clase tienen un estricto Débil pedidos

struct Foo { 
    int a, b; 
    bool operator< (Foo const& r){ 
     return a < r.a; 
    } 
    bool operator== (Foo const& r){ 
     return a==r.a&&b==r.b; 
    } 
}; 
Foo bar = { 5, 1 }; 
Foo baz = { 5, 2 }; 

ahora bar == baz es falso, pero también lo son bar < baz y baz < bar.

Tenga en cuenta que aquí el orden ignora por completo b pero b es parte de la relación de igualdad.

+0

Creo que tendría un orden estricto débil con respecto a 'a' sólo por el' operador <', ¿no? No pensé que 'operator ==' tuviera algo que ver con eso. –

+0

El problema sería sobre semántica. Si '! (A Flame

+0

¿Por qué no escribes un programa que contiene un vector de 'Foo's, lo clasificas y ves en qué orden sale :) –

Respuesta

12

Técnicamente sí, los está ordenando directamente por el miembro a, lo que debería estar bien para, por ejemplo. std::set. Básicamente se comportan como enteros, es decir. si es < by < c entonces < c, etc. No creo que el operador == afecte la validez del pedido implícito en el operador <.

Sin embargo, es una mala idea definir dos operadores en la misma clase que implican cosas diferentes al respecto, ya que es probable que resulte confuso para los usuarios de esa clase. Por lo que yo sé, no rompería directamente ningún contenedor STL ya que usan solo uno de los dos operadores, pero ciertamente me confundiría que tu puedes tener este caso donde! (Barra < baz) y! (Barra < baz) pero! (bar == baz).

En un caso como este, preferiría proporcionar como miembro solo el operador que es más natural para la clase, y hacer que el otro esté disponible a través de una estructura independiente que se puede suministrar como un parámetro de plantilla al contenedor STL. Para mí, eso deja en claro que es una forma de ordenar instancias de la clase que no es necesariamente equivalente a los otros operadores miembros.

4

De acuerdo con la entrada de Wikipedia sobre strict weak ordering, tiene las siguientes propiedades:

  • Para todas las x, no es el caso de que x < x (irreflexivity).
  • Para todo x ≠ y, si x < y, entonces no es el caso que y < x (asimétrico).
  • Para todos x, y y z, si x < yy < z entonces x < z (transitividad).
  • Para todos x, y, y z, si x es incomparable con y, y y es incomparable con z, entonces x es incomparable con z (transitividad de equivalencia).

operator< para sus clases satisface todas estas propiedades, y que por sí sola es suficiente para calificar como tener un estricto orden débil, porque por definición la relación binaria requerida es <, no ==.

Sin embargo, como menciona Peter en su answer, la definición de operator== que toma en consideración una variable de miembro adicional puede conducir a resultados poco intuitivos que probablemente confundirán a los usuarios de su clase.

0

Las clases no tienen un orden débil per se. Una orden débil estricta es una función binaria, como operator<(Foo, Foo). Una vez que se da cuenta de eso, es obvio por qué la función F no puede influir en si la función G es un SWO - es una propiedad independiente de G.Es por eso que operator== no puede influir si operator< es un SWO.

+0

Buen punto. Es la relación/predicado que define el orden, no la clase. – Flame

Cuestiones relacionadas