Question

Tout en essayant de répondre à cette question que je voulais suggérer l'utilisation de enable_if + disable_if pour permettre la surcharge d'une méthode basée sur le fait qu'un type est (ou non) polymorphique.

Je créé un petit fichier de test:

template <class T>
void* address_of(T* p,
                 boost::enable_if< boost::is_polymorphic<T> >* dummy = 0)
{ return dynamic_cast<void*>(p); }

template <class T>
void* address_of(T* p,
                 boost::disable_if< boost::is_polymorphic<T> >* dummy = 0)
{ return static_cast<void*>(p); }

struct N { int x; };


int main(int argc, char* argv[])
{
  N n;
  std::cout << address_of(&n) << std::endl;
  return 0;
}

qui semble tout à fait dompter.

Cependant gcc (3.4 ...) étouffer ceci:

  

test.cpp: En fonction int main(int, char**):
  test.cpp: 29: Erreur: appel de address_of(N*) surchargé est ambigu
  test.cpp: 17: Note: Les candidats sont: void* address_of(T*, boost::enable_if<boost::is_polymorphic<T>, void>*) [avec T = N]
  test.cpp: 20: Note: void* address_of(T*, boost::disable_if<boost::is_polymorphic<T>, void>*) [avec T = N]

Il semble assez clair à mon esprit humain qui surcharge doit être utilisé ici. Je veux dire, il semble clair que je l'ai défini une alternative et une seule fonction peut être utilisée à la fois ... et je l'aurais pensé que SFINAE prendrait soin de vicier la surcharge inutile.

Je patché vers le haut à l'aide ... (points de suspension) au lieu de disable_if et nécessitant un second argument factice ... mais je suis toujours intéressé à savoir pourquoi le starter du compilateur à ce sujet.

Était-ce utile?

La solution

Le compilateur étranglé parce que vous avez oublié le ::type de fin sur enable_if et disable_if. Les modèles sont toujours définis; il est juste que le type membre est présent si et seulement si l'expression est true (pour enable_if) ou false (pour disable_if).

template <class T>
void* address_of(T* p,
                 typename boost::enable_if< boost::is_polymorphic<T> >::type* dummy = 0)
{ return dynamic_cast<void*>(p); }

template <class T>
void* address_of(T* p,
                 typename boost::disable_if< boost::is_polymorphic<T> >::type* dummy = 0)
{ return static_cast<void*>(p); }

Sans ::type arrière, vos modèles de fonction créer simplement des pointeurs qui prennent des surcharges aux instances de enable_if ou disable_if comme second paramètre. Avec le ::type de fuite, les modèles, soit créer une surcharge avec un deuxième paramètre de type void*, ou la surcharge est retiré (à savoir le comportement souhaité).

Autres conseils

En utilisant la version de enable_if type "retour" fonctionne dans 3.4.4: gcc version 3.4.4 (cygming special, gdc 0.12, using dmd 0.125)

#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/is_polymorphic.hpp>
#include <iostream>

template <class T>
typename boost::enable_if< boost::is_polymorphic<T>, void* >::type
address_of(T* p)
{ return dynamic_cast<void*>(p); }

template <class T>
typename boost::disable_if< boost::is_polymorphic<T>, void* >::type
address_of(T* p)
{ return static_cast<void*>(p); }

struct N { int x; };


int main(int argc, char* argv[])
{
  N n;
  std::cout << address_of(&n) << std::endl;
  return 0;
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top