2011-02-14 7 views
5

veces me tienen estructuras como ésta -¿Cómo implementar operadores de igualdad C++ (in) para estructuras agregadas?

struct aggregate1 { 
    std::string name; 
    std::vector<ValueT> options; 
    size_t foobar; 
    // ... 
}; 

- donde (des) igualdad se define simplemente como (des) igualdad de todos los miembros: lhs_name == rhs_name && lhs_options == rhs_options && lhs_foobar == rhs_foobar.

¿Cuál es la "mejor" forma de implementar esto? (Best como en: (tiempo de ejecución-) Eficiencia, mantenibilidad, la legibilidad)

  • operator== en términos de operator!=
  • operator!= en términos de operator==
  • implementaciones separadas para == y !=
  • Como miembro o como funciones gratuitas?

cuenta que esta pregunta es sólo acerca de las operaciones de igualdad (en), como comparación (<, <=, ...) no tiene mucho sentido para tales agregados.

Respuesta

5

El miembro o la función gratuita es una cuestión de gusto, y la escritura de implementaciones separadas de == y != me parece aburrida, propensa a errores (puede olvidarse un miembro en uno de los dos operadores, y tomará tiempo para aviso) sin agregar nada en términos de eficiencia (llamar al otro operador y aplicar ! tiene un costo insignificante).

La decisión se limita a "¿Es mejor para poner en práctica operator== en términos de operator!= o al contrario

En mi opinión, en términos de capacidad de mantenimiento/lectura/eficacia es la misma;? Sólo lo recomiendo a hágalo de la misma manera en todas partes para obtener una mayor coherencia. El único caso en el que le gustaría preferir usar uno u otro como el "operador base" es cuando sabe que, en los tipos que contiene su estructura, ese el operador es más rápido que su negación, pero no sé cuándo podría suceder esto.

1

EN MIEMBRO, implemente como amigos e implemente el operator== (algo de STL algo los ritmos se basarán en esto, por ejemplo) y el operator!= se debe implementar como la negación del operador igual.

5

Lo haría, pero tal vez mueva operator == definition a cpp file. Deje el operador! = Estar en línea

Recuerde comparar las variables de los miembros que es más probable que difieran primero para que el resto se cortocircuite y el rendimiento sea mejor.

struct aggregate1 { 
    bool operator==(const aggregate1& rhs) const 
    { 
    return (name == rhs.name) 
    && (options == rhs.options) 
    && (foobar == rhs.foobar); 
    } 
    bool operator!=(const aggregate1& rhs) const 
    { 
    return !operator==(rhs); 
    } 

    std::string name; 
    std::vector<ValueT> options; 
    size_t foobar; 

    // ... 
}; 
+0

De acuerdo. Si aún tiene problemas con la eficiencia del tiempo de ejecución, podría considerar si es más probable que algunos miembros sean diferentes a los demás, y compararlos primero. –

0

(-: Auto respuesta :-)

me gustaría destacar un aspecto de agregados WRT eficiencia:

El orden de evaluación de op== y op!= es irrelevante para el (promedio) actuación.

Suponiendo implementaciones separadas por el momento y dado los dos extremos (a-eq) todos los subelementos igual y (b-neq) todos los subelementos inequal, disponemos de estos casos:

  • (a-eq) + operator== : necesita comparar todos sub elementos para volver realidad
  • (a-eq) + operator!=: necesita comparar todos sub elementos para volver falsa
  • (b-NEQ) + operator==: Devuelve false después del 1 de Do b elemento se determina inequal
  • (b-NEQ) + operator!=: Devuelve cierto después se determina primero el elemento sub inequal

Puesto que el rendimiento en promedio es el mismo de cualquier manera que parece - al menos para mí - más natural para implementar op!= en términos de op==, ya que me parece más natural implementar la opción de igualdad.

+0

No entiendo cómo llegas a tu conclusión. operator == y operator! = siempre tomará la misma cantidad de tiempo para calcular y no importa en qué dirección los implemente. Recuerde mantener el que está escribiendo en términos de línea para que no pague ninguna penalización de llamada. – T33C