The following template will decide if T is abstract with 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) };
};
For example: struct myClass2 { virtual void f() {} }; struct myClass1 { virtual void f() = 0; };
bool twoAbstract = isAbstract<myClass2>::result;
bool oneAbstract = isAbstract<myClass1>::result;
However, it fails in visual studio 9.0 with the error:
error C2784: 'AiLive::isAbstract<T>::No AiLive::isAbstract<T>::test(U (*)[1])' : could not deduce template argument for 'U (*)[1]' from 'myClass2'
Does anyone have an idea of what the problem is and how to fix this?
MSDN Reports that they now have an is_abstract
class since VS2008 as part of TR1 (inside the header type_traits
). However, it seems to be missing from my installation.
PS. For reasons that are long and boring, I can't reimplement this via Boost.
Update
Also, tried replacing,
template<class U> static No test( U (*)[1] );
with each of,
template<class U> static No test( U (*x)[1] );
template<class U> static No test( U (*)() );
template<class U> static No test( U (*x)() );
and
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 );
and
// Match if I can make a U2
template <typename U> static No test( U2<T> x );
No luck - all say that template argument cannot be deduced for U.