How can I determine if a type is derived from a template class? In particular, I need to determine if a template parameter has std::basic_ostream
as a base class. Normally std::is_base_of
is the tool for the job. However, std::is_base_of
only works for complete types not class templates.
I'm looking for something like this.
template< typename T >
bool is_based_in_basic_ostream( T&& t )
{
if( std::is_base_of< std::basic_ostream< /*anything*/>, T >::value )
{
return true;
}
else
{
return false;
}
}
I'm sure this can be done I can't think how.
I'm not aware of a short and concise way. But you can abuse overloading again
template< typename T, typename U >
std::true_type is_based_impl( std::basic_ostream<T, U> const volatile& );
std::false_type is_based_impl( ... );
template< typename T >
bool is_based_in_basic_ostream( T&& t ) {
return decltype(is_based_impl(t))::value;
}
It will only detect public inheritance. Note that you can instead detect derivation from ios_base
, which may work for you equally well (this test will also be positive for input streams, so it's only of limited applicability)
std::is_base_of<std::ios_base, T>
Might something like Boost's is_instance_of be what you are after?
http://www.boost.org/doc/libs/1_46_1/boost/lambda/detail/is_instance_of.hpp
Here is the short version for 1-argument templates:
#include <iostream>
#include <type_traits>
template <template <typename> class F>
struct conversion_tester
{
template <typename T>
conversion_tester (const F<T> &);
};
template <class From, template <typename> class To>
struct is_instance_of
{
static const bool value = std::is_convertible<From,conversion_tester<To>>::value;
};
template <typename T>
struct foo {};
template <typename T>
struct bar {};
int main()
{
std::cout << is_instance_of<foo<int>,foo>::value << '\n'; // This will print '1'.
std::cout << is_instance_of<bar<int>,foo>::value << '\n'; // This will print '0'.
}
Unfortunately, if you try to extend this to variadic templates, with current GCC (4.6.0) it will produce an error message. This SO answer implies that this is currently a problem of GCC and that the variadic template version is supposed to work according to the standard.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With