Domanda

Durante il tentativo di risposta questa domanda volevo suggerire l'uso di enable_if + disable_if per consentire il sovraccarico di un metodo basato sul fatto che un tipo è (o non) polimorfico.

Così ho creato un piccolo file di 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;
}

che sembra piuttosto noiosi.

Tuttavia gcc (3,4 ...) soffocare su questo:

  

test.cpp: In funzione int main(int, char**):
  test.cpp: 29: errore: Chiamata di address_of(N*) sovraccarico è
ambiguo   test.cpp: 17: Nota: i candidati sono: void* address_of(T*, boost::enable_if<boost::is_polymorphic<T>, void>*) [con T = N]
  test.cpp: 20: Nota: void* address_of(T*, boost::disable_if<boost::is_polymorphic<T>, void>*) [con T = N]

E sembra piuttosto chiaro alla mia mente umana che di sovraccarico deve essere utilizzato qui. Insomma sembra chiaro che ho definito un'alternativa e una sola funzione può essere utilizzata in un momento ... e avrei pensato che SFINAE sarebbe preso cura di invalidare il sovraccarico inutile.

I rattoppato in su utilizzando ... (puntini di sospensione) al posto di disable_if e che richiedono un secondo argomento fittizio ... ma sono ancora interessati a Perché lo starter compilatore su questo.

È stato utile?

Soluzione

Il compilatore soffocato perché si è dimenticato il ::type finale sul enable_if e disable_if. I modelli sono sempre definiti; è solo che il type membro è presente se e solo se l'espressione è true (per enable_if) o false (per 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); }

Senza la ::type finale, i modelli di funzione basta creare sovraccarichi che prendono puntatori a istanze di enable_if o disable_if come secondo parametro. Con il ::type posteriore, i modelli sia creano un sovraccarico con un secondo parametro di tipo void*, o sovraccarico viene rimossa (cioè il comportamento desiderato).

Altri suggerimenti

Utilizzando la versione "tipo di ritorno" di enable_if lavora 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;
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top