Estoy intentando usar plantillas para generar automáticamente una gran cantidad de operadores para mí. Son muy similares al siguiente código, que no se compila:

struct A
{
    int value = 1;
};

struct B
{
    int value = 2;
};  

template<typename ParamA, typename ParamB>
struct C
{
    C(int v) : value(v) {}
    
    friend C operator+(const ParamA& a, const ParamB& b)
    {
        return C(a.value + b.value);
    }
    
    int value;
};

int main()
{
    C<A, B> c = A() + B();
}

Error:

 In function 'int main()':
26:21: error: no match for 'operator+' (operand types are 'A' and 'B')
26:13: warning: unused variable 'c' [-Wunused-variable]

¿Por qué la búsqueda dependiente de argumentos no puede encontrar el operador + para A y B? Creo que podría deberse a que no está en el espacio de nombres global, ni en el mismo espacio de nombres que A o B, pero no estoy seguro de cómo solucionarlo.

¿Alguien sabe si lo que intento hacer aquí puede funcionar?

1
fortytwo 23 jul. 2020 a las 00:53

1 respuesta

La mejor respuesta

Algo como esto funcionaría:

// Struct definitions for A & B ...

struct C
{
    C(int v) : value(v) {}    
    int value;
};

template <typename ParamA, typename ParamB>
C operator+(const ParamA& a, const ParamB& b)
{
        return C(a.value + b.value);
}

Elimino la declaración de amigo del interior de la estructura C porque era innecesaria. Alternativamente, puede hacer la declaración del operador amigo dentro de las clases A, B, aunque esto puede no ser lo que desea.

struct C;

struct A
{
    int value = 1;

    template <typename paramA, typename paramB>
    friend C operator+(paramA a, paramB b);
};

struct B
{
    int value = 2;
    template <typename paramA, typename paramB>
    friend C operator+(paramA a, paramB b);
};  

// Struct definition for C
...
// Define templated operator+ function
...

Como señaló @Dani, definir operator+ como completamente genérico no es ideal. Si el operador solo es necesario para los tipos A y B, las plantillas no son necesarias. Si no es así, existen métodos para restringir los tipos.

0
M.A 23 jul. 2020 a las 10:55