2012-08-29 27 views
6

如何在編譯時測試B類是否源自std :: vector?如何測試B類是否來自類的模板族

template<class A> 
struct is_derived_from_vector { 
    static const bool value = ????; 
}; 

如何在編譯時測試B類是否來自模板族?

template<class A, template<class> class Family> 
struct is_derived_from_template { 
    static const bool value = ????; 
}; 

使用:

template<class T> struct X {}; 

struct A : X<int> {} 
struct B : std::vector<char> {} 
struct D : X<D> {} 

int main() { 
    std::cout << is_derived_from_template<A, X>::value << std::endl; // true 
    std::cout << is_derived_from_template<D, X>::value << std::endl; // true 
    std::cout << is_derived_from_vector<A>::value << std::endl; // false 
    std::cout << is_derived_from_vector<B>::value << std::endl; // true 
} 
+4

使用模板元編程,重要的是要明確您是否只需要C++ 03或者C++ 11解決方案是否好(儘管我不確定C++ 11能在這裏獲得幫助) 。作爲一個聰明的評論,考慮到你永遠不應該從標準容器繼承,原來的特性很簡單:'false':P –

+0

C++ 03。我使用msvc 2010編譯器。因此我同意使用'decltype'。 'std :: vector'就是例如ony。如果您不瞭解C++ 03解決方案,那麼也歡迎C++ 11解決方案。 –

回答

12

試試這個:

#include <type_traits> 

template <typename T, template <typename> class Tmpl> // #1 see note 
struct is_derived 
{ 
    typedef char yes[1]; 
    typedef char no[2]; 

    static no & test(...); 

    template <typename U> 
    static yes & test(Tmpl<U> const &); 

    static bool const value = sizeof(test(std::declval<T>())) == sizeof(yes); 
}; 

用法:

#include <iostream> 

template<class T> struct X {}; 

struct A : X<int> {}; 

int main() 
{ 
    std::cout << is_derived<A, X>::value << std::endl; 
    std::cout << is_derived<int, X>::value << std::endl; 
} 

注:在行標#1,你可以也使您的特質通過writint接受任何模板,它至少有一個,但可能更多的類型參數:

template <typename, typename...> class Tmpl 
+0

如果您使用'template 類Tmpl'併爲您的測試函數使用參數包,則您還應該能夠使用任意數量的參數(而不僅僅是一個)來處理模板。 –

+1

這種方法的問題是它只適用於具有單一參數的模板。即使你擴充它以接受* std :: vector的兩個參數,實現允許添加額外的模板參數(只要它爲這些參數提供默認值),所以它不會100%便攜 –

+1

@DavidRodríguez-dribeas:是的,讓它變得多變... –

1

我有我需要知道,如果一個類從一個矢量導出(如同樣的情況)-類。不幸的是,在我的項目中沒有允許使用C++-11或variadic宏。所以我的解決辦法是,這article,並在後面的一些googletest代碼的Kerrek's answer的混合物:

#include <vector> 

template <typename T> 
class is_derived_from_vector 
{ 
    typedef char Yes_t[1]; 
    typedef char No_t[2]; 

    static No_t& test(const void* const); 

    template <typename U> 
    static Yes_t& test(const std::vector<U>* const); 

public: 
    static const bool value = ((sizeof(test(static_cast<T*>(0)))) == (sizeof(Yes_t))); 
}; 

template<class T> struct X {}; 
struct A : X<int> {}; 
struct B : std::vector<char> {}; 

TEST(Example, IsDerivedFrom) 
{ 
    EXPECT_FALSE(is_derived_from_vector<A>::value); 
    EXPECT_TRUE(is_derived_from_vector<B>::value); 
} 

任何模板的共同的解決辦法,我認爲是不可能的沒有C++的使用來定義 - 11或更高。

0

我一直在尋找一個解決這個問題,不久前與

現代C++設計諮詢後:應用於泛型編程和設計模式

我是能夠建立其下面與評論中提供的內容大致相似。

#include <iostream> 
#include <type_traits> 
#include <utility> 

template <typename T, template <typename...> class U> 
struct is_derived 
{ 
private: 
    template <typename...Ts> 
    static constexpr std::true_type check(const U<Ts...>&); 
    static constexpr std::false_type check(...); 


    template <typename> 
    struct is_same 
    { 
     static constexpr bool value = false; 
    }; 

    template <typename...Ts> 
    struct is_same <U<Ts...>> 
    { 
     static constexpr bool value = true; 
    }; 

    public: 
    static constexpr bool value = 
     std::is_same<decltype(check(std::declval<T>())), 
        std::true_type>::value && 
     !is_same<T>::value; 
}; 

template <typename, typename> 
struct X 
{ 
}; 

template <typename T> 
struct Y : X <T, int> 
{ 
}; 


int main(int argc, char **argv) { 

    std::cout << std::boolalpha << is_derived<Y<int>, X>::value << std::endl; 
    std::cout << std::boolalpha << is_derived<X<int,int>, X>::value << std::endl; 
    std::cout << std::boolalpha << is_derived<int, X>::value << std::endl; 

    return 0; 
} 
相關問題