問題タブ [dynamic-dispatch]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
java - Double Dispatch/Visitor パターンを使用せずに Java の静的メソッドのディスパッチを回避する
Foo
これらのメソッドを提供するクラスを使用しています:
Java はレシーバー以外の引数で静的にディスパッチするため、 my value
(これは ですが、Object
動的な type を持つ可能性がありますGoo
) を渡すだけではなく、JVM に依存して「正しい」メソッドを動的に選択することはできません。
これは私の現在の(醜い)回避策です:
(オーバーロードされたメソッドを含むクラス)のコードを変更せずにFoo
これを行うより良い方法はありますか?
c# - リフレクションまたは動的ディスパッチ
2 つの具象パーサーによって拡張された抽象ファイル パーサー (C#) を作成しています。どちらもいくつかのチェックを実行する必要があります。現在、抽象パーサーには検証メソッドがあり、リフレクションを使用して「test」で始まる名前のすべてのメソッドを呼び出します。そうすれば、「test」で始まる名前のメソッドを追加するのと同じくらい簡単にチェックを追加できます。
最近、リフレクションの使用と、動的ディスパッチを使用する方が良いというコメントがありました。あなたへの私の質問は、リフレクションを使用しない理由と、これをどのように実装するかということです。また、動的ディスパッチを使用してこの問題を解決するにはどうすればよいですか?
c# - 変数の値に基づく動的メソッドディスパッチ
長いスイッチステートメントはしばしば眉をひそめます。解決策は、ポリモーフィズムを使用することです。しかし、私がオンにしているものがタイプコードではない場合はどうなりますか?私がやりたいのは、switchステートメントを次のようなものに置き換えることです...
これは次のものを置き換えます...
何か案は?理論的には、「if / switch」ステートメントを完全に廃止して、式の値に基づいて自動的にバインドされるメソッドを呼び出すことができると思います。
c++ - テンプレートパラメータに基づくC++での動的ディスパッチのエミュレート
これは、質問のために大幅に簡略化されています。階層があるとしましょう:
署名付きの非テンプレート関数が必要です:
関数の結果の特定のタイプがどちらかと同じタイプでa
ありb
、大きい方を持っているPrecision
場合; 次の擬似コードのようなもの:
ここA
で、およびはそれぞれ、およびB
の特定のタイプです。インスタンス化の数に関係なく動作したい。RTTIの回答は問題ありませんが、大量の比較表は避けたいと思います。何か案は?a
b
function
Derived
typeid()
c++ - C++ では、最も派生したクラスへのポインターを要求できないのはなぜですか?
(この質問は、おそらく Stroustrup を参照して回答する必要があります。)
次のように、最も派生したクラスへのポインターを要求できると非常に便利です。
ただし、このメカニズムは c++ では提供されていません。なんで?
更新、動機付けの例:
Base と Derived と Processor の代わりに、次のものがあるとします。
しかし、これを C++ で行うのは難しく、ビジター パターンのような独創的なソリューションが必要です。問題は、「CAST_TO_MOST_DERIVED」のようなものを使用するとはるかに簡単になるのに、C++ でこれを行うのが難しいのはなぜですか?
更新: ウィキペディアはすべてを知っている
ポンタス・ガッジは良い答えを持っていると思います。ウィキペディアのMultiple Dispatchのエントリから、次のビットを追加します。
「Stroustrup は、The Design and Evolution of C++のマルチメソッドの概念が好きで、C++ での実装を検討したと述べていますが、(仮想関数に匹敵する) 効率的なサンプル実装を見つけることができず、型のあいまいさの問題を解決できなかったと主張しています。 . 彼は続けて、この機能はまだあればいいのですが、上記の C/C++ の例で概説したように、ダブル ディスパッチまたは型ベースのルックアップ テーブルを使用してほぼ実装できるため、将来の言語では優先度の低い機能であると述べています。リビジョン。」
背景については、 Multi-Methodsについての簡単な要約を読むことができます。これは、私が言及したような呼び出しよりも優れているでしょう。
c++ - vtable実装を使用したc++仮想呼び出しでのマルチスレッド競合状態の疑い
vtable動的ディスパッチング実装(vtableポインターが仮想メソッドを持つオブジェクトの非表示メンバーとして格納されている)の仮想メソッド呼び出しを含む特定のC ++マルチスレッド状況で、競合状態が発生する可能性があるのではないかと疑っています。これが実際に問題であるかどうかを確認したいのですが、参照のフレームを想定できるように、boostのスレッドライブラリを指定しています。
オブジェクト「O」にboost::mutexメンバーがあり、そのコンストラクタ/デストラクタとメソッド全体がスコープロックされているとします(Monitorの同時実行パターンと同様)。スレッド「A」は、外部同期なしで(つまり、他のスレッドと同期できる「新しい」操作を囲む共有ミューテックスなしで)ヒープ上にオブジェクト「O」を構築します。ただし、「内部」がまだ存在することに注意してください。 、そのコンストラクタのスコープをロックする「監視」ミューテックス)。次に、スレッドAは、同期されたメカニズム(たとえば、同期されたリーダー/ライターキュー)を使用して、「O」インスタンス(作成したばかり)へのポインターを別のスレッド「B」に渡します(注:へのポインターのみオブジェクト自体ではなく、オブジェクトが渡されます。建設後、
スレッド「B」は、同期されたキューからオブジェクト「O」のポインタ値を読み取り、その後すぐにキューを保護しているクリティカルセクションを離れます。次に、スレッド「B」はオブジェクト「O」に対して仮想メソッド呼び出しを実行します。ここで問題が発生する可能性があると思います。
動的ディスパッチの[かなりありそうな]vtable実装での仮想メソッド呼び出しについての私の理解は、オブジェクトの非表示メンバーとして格納されているvtableポインターを取得するために、呼び出しスレッド「B」がポインターを「O」に逆参照する必要があるということです。 、およびこれはメソッド本体に入る前に発生します(当然、実行するメソッド本体は、オブジェクト自体に格納されているvtableポインターにアクセスするまで、安全かつ正確に決定されないため)。前述のステートメントがそのような実装に当てはまる可能性があると仮定すると、これは競合状態ではありませんか?
vtableポインターは、メモリの可視性を保証する操作(つまり、オブジェクト「O」のメンバー変数ミューテックスの取得)の前に、スレッド「B」によって(ヒープ内にあるオブジェクト「O」へのポインターを参照解除することによって)取得されるためです。 、それでは、「B」が、「A」がオブジェクト「O」の構造に最初に書き込んだvtableポインタ値を認識するかどうかは定かではありません。(つまり、代わりにガベージ値を認識し、未定義の動作を引き起こす可能性がありますよね?)。
上記が有効な可能性である場合、これは、スレッド間で共有される排他的に内部同期されたオブジェクトで仮想メソッド呼び出しを行うことが未定義の動作であることを意味しませんか?
また、同様に、標準はvtableの実装に依存しないため、仮想呼び出しの前にvtableポインターが他のスレッドに安全に表示されることをどのように保証できますか?コンストラクター呼び出しと、少なくとも各スレッドでの最初の仮想メソッド呼び出しを外部で同期(たとえば、「共有ミューテックスlock()/ unlock()ブロックで囲む」のように「外部」)できると思います。しかし、これはひどく不調和なプログラミングのようです。
したがって、私の疑いが真実である場合、おそらくより洗練された解決策は、メンバーのミューテックスをロックし、その後仮想呼び出しに転送するインラインの非仮想メンバー関数を使用することです。しかし、それでも、コンストラクターがコンストラクター本体自体を保護するlock()とunlock()の範囲内でvtableポインターを初期化することを保証できますか?
誰かが私がこれを片付けて私の疑いを確認/否定するのを手伝ってくれるなら、私は非常に感謝するでしょう。
編集:上記を示すコード
--ポイント(4)で、「スレッドA」がメモリに書き込んだvtableポインタ値が「スレッドB」に表示されない可能性があるという印象を受けています。これは、コンパイラがvtableポインターがコンストラクターのロックされたmutexブロック内に書き込まれるようにコードを生成します。
たとえば、各コアに専用のキャッシュがあるマルチコアシステムの状況を考えてみます。この記事によると、キャッシュは一般的に積極的に最適化されており、キャッシュコヒーレンスを強制しているにもかかわらず、同期プリミティブが含まれていない場合は、キャッシュコヒーレンスに厳密な順序付けを強制しません。
おそらく私は記事の意味を誤解していますが、それは構築されたオブジェクトへのvtableポインターの「A」の書き込み(そしてこの書き込みがコンストラクターのロックされたミューテックスブロック内で発生するという兆候がない)を意味するのではありません「B」がvtableポインターを読み取る前に、「B」によって認識されませんか?AとBの両方が異なるコア(core0の「A」とcore1の「B」)で実行される場合、キャッシュコヒーレンスメカニズムは、core1のキャッシュ内のvtableポインター値の更新(一貫性を保つ更新)を並べ替えることがあります。 「A」が書き込んだcore0のキャッシュ内のvtableポインターの値を使用して、「B」の読み取り後に発生するようにします...記事を正しく解釈している場合。
c++ - ビジターパターンは、C ++でパラメータータイプを区別するための最速の方法ですか?
ビジターパターンは、C ++でメソッドパラメータータイプの識別(事実上、メンバーのクラスではなく、パラメーターに対する単一のディスパッチ)を実現するための最速の方法ですか?まだ知られていないサブタイプの要素で呼び出したい正確なメソッドを知っている可能性があるため、のように追加の仮想メソッド呼び出しを常に行うことV::visit(A *)
はA::accept(V &v) { v.visit(this); }
望ましくありません。
次の機能と同等のものが欲しいのですが、O(1)コストが必要です。これはstd::type_info
、constexpr / switchableにできないため、dynamic_cast <>またはtypeid()ラダーでは不可能なAFAIKです。
ここでの私のオプションは何ですか?アドバイスありがとうございます!
編集:異なるメソッドタイプに複数の署名が必要ないように、フィールドを介して結果をフィードするようにサンプルコードを変更しました。ありがとう、モーリス!
最終決定: Visitor Patternの必須のダブルディスパッチコストが気に入らないことに加えて、オーバーロードのインターフェイスの肥大化を避けたかったのfoo()
ですが、これを行うための既知のクリーンなパターンはないと思います。私は結局、まっすぐな静的オーバーロードを実行して、それを1日と呼びました。とにかく、関数内にオーバーロードをカプセル化したいのは、せいぜい疑わしい目標でしょう。応答してくれてありがとう、モーリス。
python - Python での動的ディスパッチと継承
Guido の multimethod (動的ディスパッチ コード) を変更しようとしています。
http://www.artima.com/weblogs/viewpost.jsp?thread=101605
継承と、場合によっては順不同の引数を処理します。
例 (継承の問題)
各アイテムの super() が見つかるまで繰り返しチェックするよりも良い方法はありますか?
例 (引数の順序付けの問題) 衝突検出の観点からこれを考えていました。
例えば
両方をトリガーする必要があります
私は特に「エレガントな」ソリューションを探しています。あらゆる可能性を力ずくで切り抜けることができることはわかっていますが、それを避けようとしています。座って解決策を打ち出す前に、いくつかの入力/アイデアを得たかっただけです。
ありがとう
architecture - どの特定のgameObjectが衝突しているかを識別する良い方法は何ですか?
これは物理エンジンに関するものです。衝突が発生すると、2つのgameObjectが衝突しているという情報が返されます。プレーヤー、モンスター、弾丸などのすべてのエンティティは、GameObjectから派生(継承)されます。
どの特定のgameObjectが衝突しているかを識別する良い方法は何ですか?
列挙型:列挙型の使用を検討しましたが、エンティティを追加し始めるとすぐに、考えられるすべての組み合わせを追跡することが管理できなくなります。
編集:ここでC#の潜在的な解決策を見つけました:http://blogs.msdn.com/b/laurionb/archive/2009/08/13/multimethods-in-c-4-0-with-dynamic.aspx
しかし、それでも、C ++でこれを実行する必要がある場合、どのように実行しますか?
c++ - 非仮想実装を呼び出す場合、関数はvtableを介してディスパッチしますか?
私が次を持っているとしましょう:
コールバックの呼び出しは、関数シグネチャで仮想としてマークされていないため、vtableまたはストレート関数呼び出しを介して呼び出されますか?