Question

J'ai du mal avant de déclarer une fonction qui utilise boost::enable_if : le morceau de code suivant me donne une erreur de compilation:

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

Lors de la compilation, je reçois une erreur « appel ambigu à foo ». Selon la définition de enable_if, le « type » typedef correspond à void quand la condition est vraie, donc autant que je peux voir, les deux signatures de match foo. Pourquoi le compilateur pense qu'ils sont différents, et est-il une bonne façon de transmettre déclarer foo (de préférence sans répéter la partie enable_if)?

Était-ce utile?

La solution

Ceci est non seulement un problème avec enable_if. Vous obtenez la même erreur sur Visual Studio et gcc avec le code suivant:

struct TypeVoid {
  typedef void type;
};

template<typename T>
void f();

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

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

Je pense que le principal problème est que le type de retour (avant instanciation) fait partie de la signature d'une fonction de modèle. Il y a plus d'informations .

En ce qui concerne votre code, si la déclaration se réfère à la définition, vous devez correspondre à la fois:

// 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 déclaration fait référence à une autre fonction, le compilateur ne serait jamais en mesure de choisir le bon pour int , parce qu'ils sont tous deux valables. Cependant, vous pouvez désactiver la première pour int avec 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)       
{       
}

Autres conseils

Le problème est que la déclaration et la définition ne correspondent pas.

La solution est que la déclaration doit contenir exactement la même signature, et le bit 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;
}

Cette compile bien sur VC2008.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top