假设我有一些C++代码,看起来像这样:C++静态使用调度模板
class Base {
virtual void dummy() = 0;
// this is to generate a vtable, but note there is no virtual f()
};
class A : public Base {
public:
void f() { /* ... */ };
void dummy() {};
}
class B : public Base {
public:
void f() { /* different implementation from A */ };
void dummy() {};
}
template<class T1, class T2, class T3>
void doStuff(T1 &x, T2 &y, T3 &z) {
for (i=1; i<100000; ++i) {
x.f();
y.f();
z.f();
}
}
这样做的目的是为了避免内循环中的虚函数调用f()
,为了让编译器的优化。 (这显然是我的实际代码的简化版本,关于我的使用案例的详细信息,请参阅此more specific question)。
这工作正常,如果doStuff
的参数的类型在运行时知道,但如果他们不那么它失败:
int main() {
Base *x = new A();
Base *y = new B();
Base *z = new A();
doStuff(*x, *y, *z);
// oops - this instantiates to doStuff(Base &, Base &, Base &)
// and there's no Base::f().
}
来解决这个问题(由this answer的建议),它看来我要建立明确的静态调度功能:
void doStuff(Base &x, Base &y, Base &z) {
A *a_x = dynamic_cast<A*>(&x);
B *b_x = dynamic_cast<B*>(&x);
A *a_y = dynamic_cast<A*>(&y);
B *b_y = dynamic_cast<B*>(&y);
A *a_z = dynamic_cast<A*>(&z);
B *b_z = dynamic_cast<B*>(&z);
if (a_x && a_y && a_z) {
doStuff(*a_x, &a_y, &a_z);
} else if (a_x && a_y && b_z) {
doStuff(*a_x, &a_y, &b_z);
}
// ... and so on for all eight combinations of A and B.
}
但是,这是一些很烦人的重复代码,如果我有沿doStuff
线多种功能,将很快得到不可收拾,特别是如果其中任何公顷有四个或更多的论点。
所以我的问题是,有什么办法可以避免这个重复的代码?看起来,模板的一些更巧妙的使用应该能够消除它,但我不知道如何去做。
模板可能很难,但Boost的预处理器库可能会帮助您:http://www.boost.org/doc/libs/1_40_0/libs/preprocessor/doc/ –
dynamic_cast将仅适用于具有vtable的层次结构类 –
@Alex它似乎是好的,如果我添加一个虚拟的虚拟方法的基类 - 我已经编辑帖子。 – Nathaniel