ビジターパターンは、C ++でメソッドパラメータータイプの識別(事実上、メンバーのクラスではなく、パラメーターに対する単一のディスパッチ)を実現するための最速の方法ですか?まだ知られていないサブタイプの要素で呼び出したい正確なメソッドを知っている可能性があるため、のように追加の仮想メソッド呼び出しを常に行うことV::visit(A *)
はA::accept(V &v) { v.visit(this); }
望ましくありません。
// Is the Visitor pattern recommended here? (E inherits D inherits B.)
class Foo {
public:
virtual void visit(B *) { result = 3; }
virtual void visit(D *) { result = 4; }
virtual void visit(E *) { result = 5; }
private:
int result;
}; // class Foo
// Need to add generic interface to B and its children ...
class B {
public:
virtual void accept(class Foo &f) { f.visit(this); }
}; // class B
次の機能と同等のものが欲しいのですが、O(1)コストが必要です。これはstd::type_info
、constexpr / switchableにできないため、dynamic_cast <>またはtypeid()ラダーでは不可能なAFAIKです。
// O(n) search cost might get nasty with bigger hierarchies.
int foo(B *b) {
if (typeid(b) == typeid(B *)) { return 1; }
if (typeid(b) == typeid(D *)) { return 2; }
if (typeid(b) == typeid(E *)) { return 3; }
return -1;
}
ここでの私のオプションは何ですか?アドバイスありがとうございます!
編集:異なるメソッドタイプに複数の署名が必要ないように、フィールドを介して結果をフィードするようにサンプルコードを変更しました。ありがとう、モーリス!
最終決定: Visitor Patternの必須のダブルディスパッチコストが気に入らないことに加えて、オーバーロードのインターフェイスの肥大化を避けたかったのfoo()
ですが、これを行うための既知のクリーンなパターンはないと思います。私は結局、まっすぐな静的オーバーロードを実行して、それを1日と呼びました。とにかく、関数内にオーバーロードをカプセル化したいのは、せいぜい疑わしい目標でしょう。応答してくれてありがとう、モーリス。