Проверьте, наследуется ли аргумент шаблона от класса - PullRequest
11 голосов
/ 23 февраля 2011

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

Это должно работать так, как можно было бы ожидать из следующего примера:

template< class T : public CBaseClass >
  • Можно ли сделать это с помощью шаблонов, если нет, то как еще я могу это сделать?

Ответы [ 5 ]

14 голосов
/ 23 февраля 2011

Следуя примеру от Страуструпа :

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);
};
12 голосов
/ 23 февраля 2011

Вы можете использовать boost::is_base_and_derived от Boost в сочетании с BOOST_STATIC_ASSERT.Если вы используете компилятор с поддержкой TR1 или C ++ 0x, есть эквиваленты этих конструкций в стандартной библиотеке ( std :: is_base_of и оператор static_assert в C ++ 0x).

6 голосов
/ 23 февраля 2011

Если ты хочешь утверждать, делай это, как Нурк. Если вы хотите проверить, используйте is_base_of из boost или C ++ 0x. Если вы не можете использовать ни один из них, используйте 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) };
};
0 голосов
/ 10 июля 2019

Чем короче, тем лучше:

template <typename Base, typename Derived>
struct is_base {
    constexpr static bool check(Base*)   { return true; }
    constexpr static bool check(...)     { return false; }
    enum { value = check(static_cast<Derived*>(0)) };
};

Пример 1:

struct A {};
struct B  : A { };

int main(void) {
    static_assert(is_base<A,B>::value, "If Error: A is not base of B");
}

Пример 2:

template <bool, typename T=void>
struct Use {
    static std::string info() { return "Implementation that consider that A is not base of B"; }
};

template <typename T>
struct Use<true,T>  {
    static std::string info() { return "Implementation that consider that A is the base of B"; }
};


int main(void) {
    std::cout << Use<is_base<A,B>::value>::info(); //Implementation that consider that A is the base of B
}
0 голосов
/ 23 февраля 2011

Полагаю, это довольно большая проблема, нет. 3 из этого полученного товара .

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