2011-02-22 66 views
9

我想檢查給定模板的類型是否從我的項目中的基類繼承。檢查模板參數是否繼承自類

它應該像人們期望它從下面的例子:

template< class T : public CBaseClass > 
  • 是否有可能使用模板來做到這一點,如果沒有,我還能怎麼辦呢?
+0

檢查http://stackoverflow.com/questions/4532281/how-to-test-whether-class-b-is-derived-from- class-a – 2011-02-22 22:52:03

回答

10

您可以使用Boost的boost::is_base_and_derived,與BOOST_STATIC_ASSERT結合使用。如果您使用的是帶有TR1或C++ 0x支持的編譯器,那麼標準庫中的這些結構的等價物(std::is_base_of和C++ 0x中的static_assert語句)是等價的。

+0

不允許我使用boost,不幸的是 – Oktstrom 2011-02-22 21:38:06

+1

@Oktstrom:你在使用什麼編譯器?它是否支持TR1或C++ 0x? – 2011-02-22 21:40:05

+0

我正在使用Visual Studio 2010附帶的編譯器 – Oktstrom 2011-02-22 21:42:22

11

Followingexample from Stroustrup

template<class Test, class Base> 
struct AssertSameOrDerivedFrom { 
    AssertSameOrDerivedFrom() { &constraints; } 
public: 
    static void constraints() { 
    Test *pd = 0; 
    Base *pb = pd; 
    } 
}; 

template<class T> 
struct YourClass { 
    YourClass() { 
    AssertSameOrDerivedFrom<T, CBaseClass>(); 
    } 
}; 

在C++ 0x中,這將成爲:

template<class T> 
struct YourClass { 
    static_assert(std::is_base_of<CBaseClass, T>::value); 
}; 
+0

作爲一個斷言很好,但不如測試那麼好。 – 2011-02-22 22:44:11

+0

@CrazyEddie:給定問題中的代碼示例,我認爲OP的意思是「通過」檢查「來聲明」,而不是「如果C,否則做X」。 – 2011-02-22 22:49:50

6

如果要斷言,做Nurk的方式。如果你想檢查,使用boost或C++ 0x的is_base_of。如果你不能使用這類原因,使用SFINAE:

template < typename Base, typename PotentialDerived > 
struct is_base 
{ 
    typedef char (&no) [1]; 
    typedef char (&yes) [2]; 

    static yes check(Base*); 
    static no check(...); 

    enum { value = sizeof(check(static_cast<PotentialDerived*>(0))) == sizeof(yes) }; 
};