В «Современном C ++ Design», глава 2.7 («Обнаружение конвертируемости и наследования во время компиляции»): вы можете использовать sizeof
трюк:
typedef char Small;
class Big { char dummy[2]; };
Small Test(Base1);
Big Test(...);
const bool isSubclassOfBase1 = sizeof(Test(Derived1())) == sizeof(Small);
Он использует тот факт, что sizeof(...)
может определить тип, для которого вычисляется выражение, и поскольку возвращаемые значения имеют разные размеры, проверка ==
оценивается как true или false.Если Derived1 действительно является базой Base1, выбрана Small Test(Base1);
перегрузка и isSubclassOfBase1
будет истинным.
Исходя из этого, вы можете инкапсулировать проверку и сделать статическое утверждение, чтобы оно не сработало во время компиляции:
#include <boost/static_assert.hpp>
class A {};
class B: public A {};
class C {};
template<class Base, class Derived>
struct SubclassCheck
{
typedef char Yes;
class No { char dummy[2]; };
static Yes Test(Base);
static No Test(...);
enum {
Value = (sizeof(Test(*(Derived*)NULL)) == sizeof(Yes))
};
};
#define CHECK_DERIVES(b,d)\
BOOST_STATIC_ASSERT((SubclassCheck<b,d>::Value));
int
main()
{
CHECK_DERIVES(A, B);
// CHECK_DERIVES(A, C); // fails
}
Вы можете использовать любую другую реализацию статического утверждения, не обязательно Boost.