このページの2つのバージョン間の差分を表示します。
次のリビジョン
|
前のリビジョン
最新のリビジョン
両方とも次のリビジョン
|
blog:2016:2016-01-20 [2016-01-20 13:45] Decomo 作成 |
blog:2016:2016-01-20 [2016-01-20 13:58] Decomo |
新年明けましておめでとうございます(遅。開設14年目となるクソゲ~製作所を本年もよろしくお願い致します。 | 新年明けましておめでとうございます(遅。開設14年目となるクソゲ~製作所を本年もよろしくお願い致します。 |
| |
C++のテンプレートには特殊化という、特定のテンプレート引数の時にテンプレートの実体を別に定義する機能がある。だが、C#版テンプレートとも言えるジェネリックでは、なんということでしょう、特殊化が使えないではありませんか! | C++のテンプレートには特殊化という、特定の型パラメータの時にテンプレートの実体を別に定義する機能がある。だが、C#版テンプレートとも言えるジェネリックでは、なんということでしょう、特殊化が使えないではありませんか!それをどうにかしてジェネリック特殊化っぽい事をしてみたっていうお話。 |
| |
こんなコードがあったとする。 | こんなコードがあったとする。 |
| |
文章を模したデータ構造を作り、''FindChildren''メソッドで型をパラメータに子ノードを取得しているが、 | 文章を模したデータ構造を作り、''FindChildren''メソッドで型をパラメータに子ノードを取得しているが、 |
''doc.FindChildren<SectionNode>()''は正しい挙動をするものの、''doc.FindChildren<TitleNode>()''の方は空のリストが帰ってくる。''FindChildren()''は''Node.Children''しか見てないので、''SectionNode.Title''が入るはずもない。 | ''doc.FindChildren<SectionNode>()''は正しい挙動をするものの、''doc.FindChildren<TitleNode>()''の方は空のリストが帰ってくる。''FindChildren()''は''Node.Children''しか見てないので、独立したメンバ''SectionNode.Title''が入るはずはなく当然の挙動である。 |
| |
こんな時、C++なら特殊化で''FindChildren<TitleNode>''専用の処理を書けるのだが、ジェネリックは特殊化が使えないので処理が書けない。C#的には''FindChildTitleNodes()''的な別メソッドで提供するのが正しいのかもしれないが、統一感に欠けるじゃないですかやだー!(そもそもこんな糞いデータ構造にすんなって話だが例ってことで許してね。) | こんな時、C++なら特殊化で''FindChildren<TitleNode>''専用の処理が書け同一のインタフェースを提供できるのだが、前述の通りジェネリックは特殊化が使えないの。C#的には''FindChildTitleNodes()''的な別メソッドで提供するのが正しいのかもしれないが、やっぱり統一感に欠けて美しくない(そもそもこんな糞いデータ構造にすんなって話だが例ってことで許してね。) |
| |
で、知恵を振り絞って''FindChildren''を以下のようにした。 | で、知恵を振り絞って''FindChildren''を以下のようにした。 |
| |
元の''FindChildren()''を''FindChildrenInternal()''とし、''FindChildren()''には型パラメータ''T''に応じた処理を書くようにした。C++でコンパイラが自動で行ってくれる特殊化による処理の振り分けを、実行時に手動で行うような感じかしら。原理上、実行時コストは増えるが、この程度なら大した影響はないだろう。JIT様もあることだし。 | 元の''FindChildren()''を''FindChildrenInternal()''とし、''FindChildren()''には型パラメータ''T''に応じた処理を書くようにした。C++でコンパイラが自動で行ってくれる特殊化による処理の振り分けを、実行時に手動で行うような感じかしら。原理上、実行時コストは増えるが、この程度なら大した影響はないだろう。JIT様もあることだし。 |
| |
| 型が増えると''if''と特殊化処理の嵐になるが、型ごとに処理デリゲートを作って''Type''とデリゲート辞書でも作ればすっきりするので大した問題ではない。そもそも、そんな状況は最早「特殊化」の本質から外れてるので設計から見直すべきだろう。 |
| |
このコードのミソは(1)~(3)の部分。 | このコードのミソは(1)~(3)の部分。 |