実際、Doer クラス全体をパラメータ化する必要はありません。これは問題なく機能します(ccurtsingerが提案していたものに近い):
class Base {
public:
void Func() {};
};
class B1 {
public:
void Func() { cout << "in B1::Func" << endl;}
};
class B2 {
public:
void Func() { cout << "in B2::Func" << endl;}
};
class Doer {
public:
template <class B> void Do(B *pb) {pb->Func();}
};
int main() {
B1 b1;
B2 b2;
Doer d;
d.Do<B1>(&b1);
d.Do<B2>(&b2);
return 0;
}
しかし、実際にはもっと大きな問題があります。最終的に使用したと言ったコードから、コンパイル時に、どの派生クラスオブジェクトを扱っているかを正確に知っているように見えるため、次のようなコードを作成します。
for(auto i = begin(B1_container); i != end(B1_container); ++i) {
i->Func();
}
for(auto j = begin(B2_container); j != end(B2_container); ++j) {
j->Func();
}
トリックを行う必要があります。
私が言いたいのは、ここで B1-s を使用し、そこに B2-s を使用していることを前もって知っていて、Func() の呼び出しに追加コストがかからないか、またはどちらを処理する必要があるかがわからないということです。 next を使用して、それが何らかのタイプのトレイトの動的なタイプであるかどうかを確認する必要があります。これは「if」であるため、分岐が発生し、予測ミスとオーバーヘッドが発生します。関数呼び出しのコストを追加していないことに注意してください。これは、どちらの場合にもあります。