Modèle isAbstract et Visual Studio
-
03-07-2019 - |
Question
Le modèle suivant décidera si T est abstrait avec 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) };
};
Par exemple: struct myClass2 {virtual void f () {}}; struct myClass1 {void virtuel f () = 0; };
bool twoAbstract = isAbstract<myClass2>::result;
bool oneAbstract = isAbstract<myClass1>::result;
Cependant, Visual Studio 9.0 échoue avec l'erreur suivante:
error C2784: 'AiLive::isAbstract<T>::No AiLive::isAbstract<T>::test(U (*)[1])' : could not deduce template argument for 'U (*)[1]' from 'myClass2'
Quelqu'un at-il une idée du problème et de la résolution de ce problème?
MSDN indique qu'ils ont maintenant une classe is_abstract
depuis VS2008 dans le cadre de TR1 (dans l’entête type_traits
). Cependant, il semble manquer à mon installation.
PS. Pour des raisons longues et ennuyeuses, je ne peux pas le réimplémenter via Boost.
Mettre à jour
Aussi, essayé de remplacer,
template<class U> static No test( U (*)[1] );
avec chacun 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)() );
et
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 );
et
// Match if I can make a U2
template <typename U> static No test( U2<T> x );
Pas de chance - tous disent que l'argument de modèle ne peut pas être déduit pour U.
La solution
Cela fonctionne pour moi dans 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) };
};
Notez que je viens de retirer isAbstract<T>::
de l'appel à test
.
Autres conseils
Je ne suis pas sûr d'avoir noté C ++ depuis un moment, mais pouvez-vous utiliser
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;