Как проверить, является ли класс B производным от класса A? - PullRequest
7 голосов
/ 26 декабря 2010

В частности, скажем, у меня есть шаблон класса с параметрами A и B, и я хотел бы иметь ошибку компилятора (когда создается экземпляр шаблона), если B не получен из A.

template<class A, class B>
class Foo
{
    // static_assert(B is derived from A)
};

Ответы [ 3 ]

10 голосов
/ 26 декабря 2010

Об этом спрашивали очень много раз, но это так просто, что я снова выложу решение:

~Foo()
{
    A* p = (B*)0; // B is required to be a subtype of A
}
9 голосов
/ 26 декабря 2010

Проверка boost :: is_base_of .И если вы хотите сделать это сами, попробуйте код Алексея из этого вопроса :

typedef char (&yes)[1];
typedef char (&no)[2];

template <typename B, typename D>
struct Host
{
  operator B*() const;
  operator D*();
};

template <typename B, typename D>
struct is_base_of
{
  template <typename T> 
  static yes check(D*, T);
  static no check(B*, int);

  static const bool value = sizeof(check(Host<B,D>(), int())) == sizeof(yes);
};

Редактировать .Написание статического утверждения не имеет большого значения, но вот оно:

#define STATIC_ASSERT(expr, msg) \
  { stat_assert<((expr) != 0)> ERROR_##msg; (void)ERROR_##msg; } 

template<int>
struct stat_assert;

template<>
struct stat_assert<true>{};

Edit2. И вся работа, если вы не знаете, как объединить эти вещи: Код на ideone

0 голосов
/ 26 декабря 2010

То, что вам нужно, это то, что использует правила SFINAE для создания шаблона, который будет генерировать ошибку в случае, который обычно предпочтителен, но может расширяться и другим способом. Я полагаю, что у boost уже может быть шаблон, который уже делает это.

Кто-то еще дал вам код. Я оставляю этот ответ, потому что он объясняет, как работает код.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...