Pregunta

Tengo algunos problemas para declarar una función que usa boost::enable_if:el siguiente código me da un error de compilación:

// Declaration
template <typename T>
void foo(T t);

// Definition
template <typename T>
typename boost::enable_if<boost::is_same<T, int> >::type foo(T t)
{
}

int main()
{
    foo(12);
    return 0;
}

Al compilar, aparece un error de "llamada ambigua a foo".Según la definición de enable_if, el typedef 'tipo' corresponde a void cuando la condición es verdadera, por lo que puedo ver, las dos firmas de foo fósforo.¿Por qué el compilador cree que son diferentes? ¿Existe una forma correcta de reenviar la declaración? foo (preferiblemente sin repetir el enable_if parte)?

¿Fue útil?

Solución

Esto no es sólo un problema con enable_if. Se obtiene el mismo error en Visual Studio y gcc con el siguiente código:

struct TypeVoid {
  typedef void type;
};

template<typename T>
void f();

template<typename T>
typename T::type f() {
}

int main()
{
  f<TypeVoid>();
  return 0;
}

Creo que el problema principal es que el tipo de retorno (antes de instancias) es parte de la firma de una función de plantilla. Hay más información aquí .

En cuanto a su código, si la declaración se refiere a la definición, debe coincidir tanto:

// Declaration       
template <typename T>       
typename boost::enable_if<boost::is_same<T, int> >::type foo(T t);       

// Definition       
template <typename T>       
typename boost::enable_if<boost::is_same<T, int> >::type foo(T t)       
{       
}

Si la declaración se refiere a una función diferente, el compilador nunca sería capaz de elegir el correcto para int s, ya que ambos son válidos. Sin embargo, puede desactivar el primero para int s utilizando disable_if

// Other function declaration
template <typename T>
typename boost::disable_if<boost::is_same<T, int> >::type foo(T t);

// Defition
template <typename T>       
typename boost::enable_if<boost::is_same<T, int> >::type foo(T t)       
{       
}

Otros consejos

El problema es que la declaración y la definición no coinciden.

La solución es que la declaración debe contener exactamente la misma firma, y ​​el enable_if poco.

#include <boost/type_traits/is_same.hpp>
#include <boost/utility/enable_if.hpp>

// Declaration
template <typename T>
typename boost::enable_if<boost::is_same<T, int> >::type foo(T t);

// Definition
template <typename T>
typename boost::enable_if<boost::is_same<T, int> >::type foo(T t)
{
}

int main()
{
    foo(12);
    return 0;
}

Esto se compila bien en VC2008.

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