Jai*_*ime 3 c++ templates static-assert type-traits
我想要防止的是不止一个基于C的模板来自D(即应该只有一个C派生的实例).希望C或B中的静态断言可以解决这个问题.
// My Classes
template <class T>
class A {};
class B {};
template <class T, class S>
class C : public B, public virtual A<T> {};
// Someone elses code using my classes
class D : public C<Type1, Type2>, public C<Type3, Type4>
{
};
Run Code Online (Sandbox Code Playgroud)
就目前而言,不可能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
}
Run Code Online (Sandbox Code Playgroud)
我必须将断言放在构造函数而不是类定义中,因为在实例化类模板时,某些类型是不完整的.不幸的是,这意味着只会报告实际实例化的类的错误.