Проверка наследования с помощью шаблонов в C ++ - PullRequest
2 голосов
/ 11 сентября 2008

У меня есть класс, который является классом-оберткой (служит общим интерфейсом) для другого класса, реализующего необходимые функциональные возможности. Итак, мой код выглядит следующим образом.

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

Теперь, как мне убедиться, что ImplementationClass может быть получен только из набора классов, аналогично обобщению java

<? extends BaseClass>

синтаксис

Ответы [ 3 ]

7 голосов
/ 11 сентября 2008

Это многословно, но вы можете сделать это так:

#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 .

Как сказал Ферруччо, более простая, но менее мощная реализация:

#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));
};
2 голосов
/ 11 сентября 2008

В текущем положении вещей нет другого способа, кроме как с помощью комментариев или стороннего решения. Boost предоставляет для этого библиотеку проверки концепции , и я думаю, что у gcc также есть реализация. Концепции находятся в списке улучшений C ++ 0x, но я не уверен, что вы можете указать подтипы - они больше для «должны поддерживать эти операции», что (примерно) эквивалентно.

Редактировать: В Википедии есть раздел о понятиях в C ++ 0x, который значительно легче читать, чем проекты предложений.

0 голосов
/ 11 сентября 2008

См. Собстубу собственные слова по этому вопросу .

В основном небольшой класс, который вы где-то создаете, например, конструктор шаблонных классов.

template<class T, class B> struct Derived_from {
    static void constraints(T* p) { B* pb = p; }
    Derived_from() { void(*p)(T*) = constraints; }
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...