2012-08-29 24 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; 
} 
相关问题