2011-05-13 112 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的問題,並且可變模板版本應該按照標準工作。