template IsAbstract e visual studio
-
03-07-2019 - |
Pergunta
O modelo a seguir irá decidir se T é abstrato com 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 exemplo: struct MinhaClasse2 {virtual void f () {}}; struct MyClass1 {virtual void f () = 0; };
bool twoAbstract = isAbstract<myClass2>::result;
bool oneAbstract = isAbstract<myClass1>::result;
No entanto, ele falha no visual studio 9.0 com o erro:
error C2784: 'AiLive::isAbstract<T>::No AiLive::isAbstract<T>::test(U (*)[1])' : could not deduce template argument for 'U (*)[1]' from 'myClass2'
Alguém tem uma idéia de qual é o problema e como corrigir isso?
MSDN relatórios que eles agora têm uma classe is_abstract
desde VS2008 como parte de TR1 (dentro do type_traits
cabeçalho). No entanto, parece estar faltando a minha instalação.
PS. Por razões que são longos e chato, eu não posso reimplementar esta via Boost.
Atualização
Além disso, tentou substituir,
template<class U> static No test( U (*)[1] );
com cada um,
template<class U> static No test( U (*x)[1] );
template<class U> static No test( U (*)() );
template<class U> static No test( U (*x)() );
e
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 );
e
// Match if I can make a U2
template <typename U> static No test( U2<T> x );
Sem sorte -. Todos dizem que argumento de modelo não pode ser deduzida para U
Solução
Isso funciona para mim em 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 Eu só tinha que remover isAbstract<T>::
da chamada para test
.
Outras dicas
Não tenho certeza como eu nota fiz C ++ por um tempo, mas você pode usar
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;