Frage

Während auf Antwort versuchen, diese Frage Ich wollte schlägt die Verwendung von enable_if + disable_if der Überlastung eines Verfahren auf der Grundlage der Tatsache Rechnung zu tragen, dass ein Typ war (oder nicht) polymorph.

So habe ich eine kleine Testdatei erstellt:

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

das ist ganz scheint zähmen.

Allerdings gcc (3.4 ...) Choke auf diese:

  

test.cpp: In Funktion int main(int, char**):
  test.cpp: 29: Fehler: Aufruf überladener address_of(N*) ist mehrdeutig
  test.cpp: 17: Anmerkung: Kandidaten sind: void* address_of(T*, boost::enable_if<boost::is_polymorphic<T>, void>*) [mit T = N]
  test.cpp: 20: Anmerkung: void* address_of(T*, boost::disable_if<boost::is_polymorphic<T>, void>*) [mit T = N]

Es scheint ziemlich klar zu meinem menschlichen Geist, die Überlastung sollte hier verwendet werden. Ich meine, es scheint klar, dass ich eine Alternative definiert haben und nur eine Funktion zu einem Zeitpunkt verwendet werden ... und ich hätte gedacht, dass SFINAE kümmern würde die unnötige Überlastung der ungültig zu machen.

ich gepatcht es mithilfe ... (Auslassung) statt disable_if und erfordern ein Dummy zweites Argument ... aber ich bin interessiert noch, warum die Compiler Drossel zu diesem Thema.

War es hilfreich?

Lösung

Der Compiler gedrosselt, weil Sie die hintere ::type auf enable_if und disable_if vergessen. Die Vorlagen sind immer definiert; es ist nur, dass das Mitglied type vorhanden ist, wenn und nur wenn der Ausdruck true (für enable_if) oder false (für 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); }

Ohne die Hinter ::type, Ihre Funktion Vorlagen erstellen, Überlastungen, die Zeiger auf Instanzen von enable_if oder disable_if als zweiten Parameter übernehmen. Mit dem Hinter ::type entweder die Vorlagen eine Überladung mit einem zweiten Parameter des Typ void* erstellen oder die Überlast entfernt wird (das heißt das gewünschte Verhalten).

Andere Tipps

Mit der "Rückgabetyp" -Version von enable_if arbeitet in 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;
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top