如果您确实需要能够跟踪祖先和枚举类型,您可能需要查看Loki TypeLists。我不确定如果没有大量工作,您所要求的是否真的可行。确保你没有在这里过度设计。
稍微不同的是,如果您打算以这种方式使用 MI(即可怕的菱形),那么您应该非常明确地说明您想要哪个虚拟成员。我想不出一个好的案例,你想选择B::fn()
over的语义C::fn()
而不在编写时明确做出决定D
。您可能会根据单个方法的作用来选择一个(甚至两者)。一旦做出决定,要求继承的更改不会改变期望或语义接口。
如果您真的担心换入一个新类,E
而不是say B
whereE
不下降B
但提供相同的接口,那么您应该真正使用模板方法,尽管我不确定为什么那里有一个static_cast<>
.. .
struct A {
virtual ~A() {}
virtual void f() = 0;
};
struct B: A {
virtual void f() { std::cout << "B::f()" << std::endl; }
};
struct C: A {
virtual void f() { std::cout << "C::f()" << std::endl; }
};
template <typename Base1, typename Base2>
struct D: Base1, Base2 {
void g() { Base1::f(); Base2::f(); }
};
int main() {
D<B,C> d1;
D<C,B> d2;
d1.g();
d2.g();
return 0;
}
// Outputs:
// B::f()
// C::f()
// C::f()
// B::f()
工作正常,看起来更容易看。