tengo el siguiente código (lo siento por el gran trozo de código, pero no podía reducirlo más)plantilla ambigua rareza
template <bool B>
struct enable_if_c {
typedef void type;
};
template <>
struct enable_if_c<false> {};
template <class Cond>
struct enable_if : public enable_if_c<Cond::value> {};
template <typename X>
struct Base { enum { value = 1 }; };
template <typename X, typename Y=Base<X>, typename Z=void>
struct Foo;
template <typename X>
struct Foo<X, Base<X>, void> { enum { value = 0 }; };
template <typename X, typename Y>
struct Foo<X, Y, typename enable_if<Y>::type > { enum { value = 1 }; };
int main(int, char**) {
Foo<int> foo;
}
Pero falla al compilar con gcc (v4.3) con
foo.cc: In function ‘int main(int, char**)’:
foo.cc:33: error: ambiguous class template instantiation for ‘struct Foo<int, Base<int>, void>’
foo.cc:24: error: candidates are: struct Foo<X, Base<X>, void>
foo.cc:27: error: struct Foo<X, Y, typename enable_if<Y>::type>
foo.cc:33: error: aggregate ‘Foo<int, Base<int>, void> foo’ has incomplete type and cannot be defined
Bien, entonces es ambiguo. pero no esperaba que fuera un problema, ya que al usar la especialización casi siempre habrá alguna ambigüedad. Sin embargo, este error solo se desencadena al usar la clase con enable_if<...>
, si lo reemplazo con una clase como la siguiente no hay problema.
template <typename X, typename Y>
struct Foo<X, Y, void > { enum { value = 2 }; };
¿Por qué esta clase no causa una ambigüedad mientras que las otras sí? ¿No son los dos lo mismo para las clases con un verdadero :: valor? De todos modos, cualquier sugerencia sobre lo que estoy haciendo mal se aprecia.
Gracias por las respuestas, mi problema real (para obtener el compilador para seleccionar la primera especialización) se resolvió mediante la sustitución de struct Foo<X, Base<X>, void>
con struct Foo<X, Base<X>, typename enable_if< Base<X> >::type >
que parece funcionar de la manera que quiero.
El editor de rebajas no es wysiwyg con respecto a
Lo arreglé antes, sobrescribió mis cambios :) Si lo desea, puede volver a mi edición (utilicé el botón "10101", que marca automáticamente las cosas como código, debe usar ese botón también). –
Uhjm ... Lo hice de nuevo sin leer tu comentario litb –