es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Problema de diseño de Sobrecarga Global de Operadores en C++

Tengo un problema con mi diseño actual.

Tengo una clase que se puede construir con cualquier argumento. Si ayuda conceptualmente, piense en T como si fuera para lambdas.

// 1
template<class t="">
foo(T) {/*...*/}

Esta clase sobrecarga muchos operadores, como !=

// 2
template<class t="">
bool foo::operator!=(const T&) {/*...*/}

Los operadores son independientes del orden izquierdo versus derecho, por lo que he definido esto globalmente:

// 3
template<class t="">
bool operator!=(T const& lhs, const foo& rhs) {return rhs != lhs;}

Como resultado, obtengo muchas llamadas ambiguas al operador !=. Esto se debe a que intenta utilizar el 3, convirtiendo el segundo argumento en foo ya que lo acepta implícitamente, luego intercambia el orden de los argumentos y llama a la función miembro. Pensé que esto se evitaría haciendo que los argumentos de 3 fueran const&, pero estaba equivocado.

Se me ocurrieron algunas opciones, pero no me gustó ninguna de ellas.

  1. Hacer que el constructor sea explícito (lo cual arruina el 40% del syntactic sugar, el objetivo de esta clase)
  2. Eliminar el operador global
  3. Poner el operador global en un espacio de nombres y luego utilizar using namespace cuando los necesite

¿Cuáles son mis otras opciones?

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Como experto en TI especializado en c++, c++17 y sobrecarga de operadores, sugiero explorar las siguientes opciones para abordar el problema con su diseño actual:

    1. Utilizar SFINAE para restringir el constructor y aceptar solo tipos que sean convertibles a T, en lugar de cualquier argumento único. Esto podría evitar la ambigüedad en las llamadas a operator!= cuando el segundo argumento no sea del tipo foo.
    2. Implementar un operador global más específico para cada tipo que pueda causar ambigüedad, en lugar de un operator!= genérico. Esto requeriría código adicional, pero podría proporcionar más claridad y evitar ambigüedades en las llamadas a operator!=.
    3. Mover el operator!= a la clase foo y eliminar el operador global. Esto haría que las llamadas a operator!= se resolvieran sin ambigüedades. Sin embargo, esto podría afectar el diseño general y los objetivos de la clase.
    4. Utilizar el despacho de etiquetas para habilitar/deshabilitar selectivamente el operador global o el operator!= en función del tipo del segundo argumento. Esta podría ser una solución más compleja, pero proporcionaría una forma flexible de abordar el problema de ambigüedad.

    Considere cuidadosamente estas opciones y elija la que mejor se ajuste a los requisitos y objetivos de su proyecto.

Comments are closed.