Pregunta

La siguiente plantilla decidirá si T es abstracto con g ++.

/**
   isAbstract<T>::result is 1 if T is abstract, 0 if otherwise.
 */
template<typename T>
class isAbstract
{
   class No { };
   class Yes { No no[3]; }; 

   template<class U> static No test( U (*)[1] ); // not defined
   template<class U> static Yes test( ... ); // not defined 

public:
   enum { result = sizeof( isAbstract<T>::template test<T>( 0 ) ) == sizeof(Yes) }; 
};

Por ejemplo:     struct myClass2 {virtual void f () {}};     struct myClass1 {virtual void f () = 0; };

bool twoAbstract = isAbstract<myClass2>::result;
bool oneAbstract = isAbstract<myClass1>::result;

Sin embargo, falla en Visual Studio 9.0 con el error:

error C2784: 'AiLive::isAbstract<T>::No AiLive::isAbstract<T>::test(U (*)[1])' : could not deduce template argument for 'U (*)[1]' from 'myClass2'

¿Alguien tiene una idea de cuál es el problema y cómo solucionarlo?

MSDN informa que ahora tienen una clase is_abstract desde VS2008 como parte de TR1 (dentro del encabezado type_traits). Sin embargo, parece que falta en mi instalación.

PS. Por razones que son largas y aburridas, no puedo volver a implementar esto a través de Boost.

Update

Además, intenté reemplazarlo,

template<class U> static No test( U (*)[1] ); 

con cada uno de,

template<class U> static No test( U (*x)[1] );
template<class U> static No test( U (*)() );
template<class U> static No test( U (*x)() );

y

template <typename U>
struct U2 : public U
{
   U2( U* ) {}
};

// Match if I can make a U2
template <typename U> static No test( U2<U> x  );

y

// Match if I can make a U2
template <typename U> static No test( U2<T> x  );

Sin suerte: todos dicen que el argumento de plantilla no se puede deducir para U.

¿Fue útil?

Solución

Esto funciona para mí en VC9:

template<typename T>
class isAbstract
{
    class No { };
    class Yes { No no[3]; }; 

    template<class U> static No test( U (*)[1] ); // not defined
    template<class U> static Yes test( ... ); // not defined 

public:
    enum { result = sizeof( test<T>( 0 ) ) == sizeof(Yes) }; 
};

Observe que solo tuve que eliminar isAbstract<T>:: de la llamada a test.

Otros consejos

No estoy seguro, ya que he notado que hice C ++ por un tiempo, pero ¿puedes usarlo?

template< typename  T, typename  U>
class isAbstract
{
   class No { };
   class Yes { No no[3]; }; 

   template<class U> static No test( U (*)[1] ); // not defined
   template<class U> static Yes test( ... ); // not defined 

public:
   enum { result = sizeof( isAbstract<T>::template test<T>( 0 ) ) == sizeof(Yes) }; 
};


bool twoAbstract = isAbstract<myClass2, SomeTypeU>::result;
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top