Как определить, получен ли тип из класса шаблона?
Как определить, получен ли тип из класса шаблона? В частности, мне нужно определить, имеет ли параметр шаблона std::basic_ostream
как базовый класс. Обычно std::is_base_of
является инструментом для задания. Однако std::is_base_of
работает только для полных типов, а не для шаблонов классов.
Я ищу что-то вроде этого.
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;
}
}
Я уверен, что это можно сделать, я не могу думать, как это сделать.
Ответы
Ответ 1
Я не знаю короткого и краткого пути. Но вы можете злоупотреблять перегрузкой снова
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;
}
Он будет обнаруживать только публичное наследование. Обратите внимание, что вы можете вместо этого определять вывод из ios_base
, который может работать для вас одинаково хорошо (этот тест также будет положительным для входных потоков, поэтому он ограничен только применительно)
std::is_base_of<std::ios_base, T>
Ответ 2
Возможно, что-то вроде Boost is_instance_of, что вы после?
http://www.boost.org/doc/libs/1_46_1/boost/lambda/detail/is_instance_of.hpp
Вот короткая версия для шаблонов с одним аргументом:
#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'.
}
К сожалению, если вы попытаетесь распространить это на вариативные шаблоны, то с помощью текущего GCC (4.6.0) оно выдает сообщение об ошибке. Этот ответ SO подразумевает, что в настоящее время это проблема GCC и что версия вариационного шаблона должна работать в соответствии со стандартом.