就目前而言,不可能B
或C
检测到更多派生类继承自什么,因此您不能在那里添加断言。但是,通过添加“奇怪地递归”模板参数,您可以知道C
派生类是什么。不幸的是,这确实需要派生类提供正确的模板参数,并且没有办法强制执行。
然后,您可以确定派生类是否B
以多种方式继承;它是一个基类,但您不能将派生类指针转换为B*
(因为该转换不明确)。请注意,这不一定表示多重继承;如果有非公共继承,测试也会失败。
所以我能想到的最好的解决方案是:
#include <type_traits>
template <class T> class A {};
class B {};
template <class T, class S, class D>
class C : public B, public virtual A<T> {
public:
C() {
static_assert(
std::is_base_of<C,D>::value && std::is_convertible<D*,B*>::value,
"Multiple inheritance of C");
}
};
struct Type1 {};
struct Type2 {};
struct Type3 {};
struct Type4 {};
class Good : public C<Type1, Type2, Good> {};
class Evil : public C<Type1, Type2, Evil>, public C<Type3, Type4, Evil> {};
int main()
{
Good good;
Evil evil; // Causes assertion failure
}
我不得不将断言放在构造函数而不是类定义中,因为当类模板被实例化时,有些类型是不完整的。不幸的是,这意味着只会为实际实例化的类报告错误。