2011-05-13 100 views
11

如何确定类型是否来自模板类?特别是,我需要确定模板参数是否具有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

只是想扔......你可以用if语句中的一条返回行代替整个if/else分支! – AshleysBrain 2011-05-13 22:34:14

+0

是'typename T'的完整类型吗?你会在代码中指定为“/ *任何* /'? – iammilind 2011-05-14 06:29:15

+0

在我的情况下,我只希望看到那里的整体字符类型。我相信basic_ostream不能被实例化,除非'/ * anything * /'是一个完整的类型。 – 2011-05-14 13:11:30

回答

12

我不知道简短而简洁的方法。但你可以再次滥用超载

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> 
+1

检查'std :: ios_base'的问题是,它也会检测输入流,这可能违反了OP所需的语义。 – ildjarn 2011-05-13 22:38:00

+0

@ildjarn我同意。我想我应该更清楚。谢谢你明确指出。修正:) – 2011-05-13 22:57:30

5

可能会像Boost的is_instance_of是你在之后?

http://www.boost.org/doc/libs/1_46_1/boost/lambda/detail/is_instance_of.hpp

这里是1 - 参数模板的短版:

#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'. 
} 

不幸的是,如果你试图将其扩展到可变参数模板,与目前的海湾合作委员会(4.6.0),它会产生一条错误消息。 This SO answer意味着这是目前GCC的问题,并且可变模板版本应该按照标准工作。