2

我有一个类,它是围绕另一个实现所需功能的类的包装类(用作公共接口)。所以我的代码看起来像这样。

template<typename ImplemenationClass> class WrapperClass {
// the code goes here
}

现在,我如何确保ImplementationClass只能从一组类派生,类似于 java 的泛型

<? extends BaseClass>

句法?

4

3 回答 3

7

它很冗长,但你可以这样做:

#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));
};
于 2008-09-10T22:43:38.140 回答
2

在目前的情况下,除了通过评论或第三方解决方案之外没有其他好的方法。Boost为此提供了一个概念检查库,我认为gcc也有一个实现。概念在 C++0x 改进列表中,但我不确定您是否可以指定子类型 - 它们更多地用于“必须支持这些操作”,这(大致)等效。

编辑:维基百科有这部分关于 C++0x 中的概念,这比草案提案更容易阅读。

于 2008-09-10T22:38:00.603 回答
0

请参阅Stoustrup 自己关于该主题的话

基本上是一个小类,您可以在某处实例化,例如模板类构造函数。

template<class T, class B> struct Derived_from {
    static void constraints(T* p) { B* pb = p; }
    Derived_from() { void(*p)(T*) = constraints; }
};
于 2008-09-11T13:41:08.497 回答