使用C ++中的模板检查继承
时间:2020-03-05 18:51:07 来源:igfitidea点击:
我有一个类,它是包装器类(用作公共接口),围绕另一个实现所需功能的类。所以我的代码看起来像这样。
template<typename ImplemenationClass> class WrapperClass { // the code goes here }
现在,我如何确保ImplementationClass
只能从一组类中派生,类似于Java的泛型
<? extends BaseClass>
句法?
解决方案
回答
在当前情况下,除了通过注释或者第三方解决方案之外,没有其他好方法。 Boost为此提供了一个概念检查库,我认为gcc也有一个实现。概念在C ++ 0x改进列表中,但是我不确定是否可以指定子类型,这些子类型更多地用于(必须)等效的"必须支持这些操作"。
编辑:Wikipedia有关于C ++ 0x中概念的这一部分,比起草提案要容易阅读得多。
回答
它很冗长,但是我们可以这样:
#include <boost/utility/enable_if.hpp> #include <boost/type_traits/is_base_of.hpp> struct base {}; template <typename ImplementationClass, class Enable = void> class WrapperClass; template <typename ImplementationClass> class WrapperClass<ImplementationClass, typename boost::enable_if< boost::is_base_of<base,ImplementationClass> >::type> {}; struct derived : base {}; struct not_derived {}; int main() { WrapperClass<derived> x; // Compile error here: WrapperClass<not_derived> y; }
这需要一个对标准有良好支持的编译器(最新的编译器应该可以,但Visual C ++的旧版本则不能)。有关更多信息,请参见Boost.Enable_If文档。
正如Ferruccio所说,一种更简单但功能不那么强大的实现:
#include <boost/static_assert.hpp> #include <boost/type_traits/is_base_of.hpp> struct base {}; template <typename ImplementationClass> class WrapperClass { BOOST_STATIC_ASSERT(( boost::is_base_of<base, ImplementationClass>::value)); };
回答
参见Stoustrup自己关于该主题的文字。
基本上是一小类,我们可以在某个地方实例化,例如模板化类的构造函数。
template<class T, class B> struct Derived_from { static void constraints(T* p) { B* pb = p; } Derived_from() { void(*p)(T*) = constraints; } };