- 727 名前:デフォルトの名無しさん (ワッチョイ f35b-tpgq) mailto:sage [2017/03/18(土) 20:19:09.95 ID:waR+gchT0.net]
- 分かるか?
完全に「直接呼び出し」にするには動的データとして「メンバ関数オブジェクト」みたいな物を作り、 それの展開ルーチンをインラインで埋め込まないといけないんだよ。 (サブルーチンで呼び出すと結局2段呼び出しになるだけ無駄) だったらそのままその「展開ルーチン」→「ターゲットメンバ関数」の2段呼び出しでもいいや、ってことになるだろ。 それがVC++でこの部分の直接呼び出し最適化をしていない理由だと思うよ。 多分さほど効果がないんだよ。(やる事自体は難しくない) 表面的な原因は、「第1引数がbindされた関数ポインタ」「第2引数がbindされた関数ポインタ」が 同じ型になってしまうことだよ。だからといって、これらが別型なのは言語として糞だろ。 明示的に分かりやすくその場で代入されている場合は、 これらを別扱いすればいいだけだから比較的楽に対応出来る。 だけど一旦ポインタとして受けられた場合、どれになるかは分からなくなるので無理になる。 それで、ポインタ自体にその情報を与えて動的モドキで対応するよりも、 単純に2段呼び出ししたほうがマシ、という判断が為された、ということだよ。VCでは。 ただ、2段呼び出しは「継承したクラス」を自分で書いた場合で、 std::bindってevalするわけではなくて、静的なライブラリ(=データしか作成出来ない)だよな? だったら内部的に上記「メンバ関数オブジェクト」方式になっている可能性が高く、 2段呼び出しで汎用ルーチンで展開=一番遅いパターンだと思うけどね。 まあここら辺はそっちの方が詳しい気がするが。 で、改めて聞くが、何が言いたいんだ? 俺はCコンパイラを作っているわけではないし、俺に文句言われても知らんがな。 結論としては、 > std::bind()自体の書き方や関数オブジェクトの書き方がよほどアレでない限りはF::calc()直接呼出し相当のコードになる は間違いだね。理由は上記、完全精査はかなり難しいからだ。 (もし出来てるのならスゲーとは思うけど)
|

|