Pregunta

Si tengo una clase base de plantilla con un método de plantilla:

template <typename T>
class S
{
public:

    template <typename U>
    void f(U p, typename enable_if<is_same<T, U> >::type*dummy = 0)
    {
        std::cout << p << std::endl;
    }
};

Para el ejemplo, simplifico el método: debe "existe" solo si t == u

Si a es esta clase:

class A : public S<int> {};

Entonces tengo lo que quiero:

int i = 1;
A a;
a.f(i);

compilación, pero

double d = 2.0;
a.f(d);

No compila: Error: no hay función coincidente para la llamada a 'A :: F (Double &)' Es el comportamiento esperado.

Ahora hemos herido de S<double> además :

class A : public S<int>, public S<double> {};

Entonces el siguiente código no compila:

int i = 1;
A a;
a.f(i);
error: request for member ‘f’ is ambiguous

error: candidates are: template<class U> void S::f(U, typename
boost::enable_if<boost::is_same<T, U>, void>::type*) [with U = U, T =
double]

error:                 template<class U> void S::f(U, typename
boost::enable_if<boost::is_same<T, U>, void>::type*) [with U = U, T =
int]

Esperaba que no hubiera ambigüedad: f<int> existe solo para S<int>

En el error del compilador, podemos notar que T se sabe cuando se compila esta pieza de código, pero no u (u = u).

¿Alguna explicación o "solución alternativa"?

¿Fue útil?

Solución

Prueba esto:

a.S<int>::f(i);

... o alternativamente inyectar la función en A, p.ej

class A : public S<int>, public S<double> 
{
public:
  using S<int>::f;
  using S<double>::f;
};

Otros consejos

Tienes razón, solo existe en S, pero dos veces. Una vez para cada tipo, int y duplicar. Entonces, en su caso, deberá especificar exactamente a qué función desea llamar. La solución de NIM funciona así.

Otros han dado buenas soluciones, pero quiero responder a esa otra pregunta que tenía

Esperaba que no hubiera ambigüedad: f<int> existe solo para S<int>.

Usted dijo a.f(i) Entonces primero debe buscar el nombre f en A. Encuentra dos fs. En S<int> y S<double>. En el tiempo de búsqueda de nombre, aún no sabe que más tarde solo podría haber seleccionado S<int>::f como ganador porque S<double>::f sería tirado por Sfinae. La clara separación de la búsqueda de nombre y la resolución de sobrecarga y la deducción de argumentos de plantilla no permite tal entremezcla.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top