Pergunta

Eu tenho alguns problemas para a frente declarar uma função que usa boost::enable_if : o seguinte pedaço de código me dá um erro do compilador:

// 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;
}

Ao compilar, eu recebo uma "chamada ambígua para foo" erro. De acordo com a definição de enable_if, o 'tipo' typedef corresponde a void quando a condição for verdadeira, assim, tanto quanto eu posso ver, as duas assinaturas de jogo foo. Porque o compilador acha que eles são diferentes, e existe uma maneira correta de foo declarar a frente (de preferência sem repetir a parte enable_if)?

Foi útil?

Solução

Este não é apenas um problema com enable_if. Você obtém o mesmo erro no Visual Studio e gcc com o seguinte 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;
}

Eu acho que o principal problema é que o tipo de retorno (antes instanciação) é parte da assinatura de uma função de modelo. Há mais informações aqui .

No que diz respeito o seu código, se a declaração refere-se à definição, você deve combinar ambos:

// 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)       
{       
}

Se a declaração refere-se a uma função diferente, o compilador nunca seria capaz de escolher o correto para int s, porque ambos são válidos. No entanto, você pode desativar o primeiro para int s usando 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)       
{       
}

Outras dicas

O problema é que a declaração ea definição não coincidem.

A solução é que a declaração deve conter a mesma assinatura exata, eo pouco a enable_if.

#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;
}

Este compila bem em VC2008.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top