様々な小さなタイプを表す型識別器enum
を考える:C++では、実行時型のディスクリミネータをテンプレートインスタンスにマップするにはどうすればよいですか(手動ですべてを列挙する必要はありません)。
enum TypesEnum {
IntT,
DoubleT,
ShortStringT
};
は、私がtemplate SomeType<typename A, typename B, typename C>
があるとします。これは、レイアウト/ストライドが型によって決まるメモリマップファイルのセットを読み書きする型です。実行時の型は上記のenum discriminatorsの三つ組として格納されます。
SomeType<A,B,C> => SomeType<B,A,C>
などのように、これらのファイルをロードして操作できるさまざまなツールを記述する必要があります。したがって、これらのツールでは、ディスク上の型識別器を正しいタイプのテンプレートインスタンスで実装された汎用のラムダラップ処理に変換するかなり面倒なレイヤーがあります。
これは次のようになります。template<A,B,C> class SomeOperation
でtypedef std::function<bool(void)> some_op_fn_t
、実装は、ディスクへの副作用との仕事の束を行う
static std::map< std::tuple<Discrim, Discrim, Discrim>, some_op_fn_t > =
{
{std::make_tuple(IntT, DoubleT, ShortStringT), SomeOperation<int,double,char[16]>() },
std::make_tuple(IntT, IntT, ShortStringT), SomeOperation<int,int,char[16]>() },
...
};
... look up the correct function pointer and call it with the path to the files ...
。
これで、タイプのリストとさまざまな操作の数が増えるにつれて、これはすぐに面倒になります。トリックは私です抽象的な/仮想値の型で動作するタイプ消去SomeType
を単に持っている仮想継承を使用することはできません。インダイレクションとポインター追跡を行うのは非常に遅すぎます。 BLASに直接渡すのに適した、デッド・レコニングと連続した、パックされたバリュー・データ(フロートとダブルの場合)に対応する必要があります。
このようなインターフェース/レイヤーの作成を自動化する技術はありますか?タイプレベルの組み合わせのようなものが役に立ちます。ここでは、列挙型を型に一度だけ接続し、マッピングのすべてのインスタンスを展開できます。それは可能ですか?
私はコードを生成するスクリプトを書くことができます最悪の場合、しかし、うわ...
簡単な部分:あなたは 'int'、' DoubleT'にdouble' 'に' 'enum' IntT'をマッピングする特性を持っている(および/または可能逆に)。より複雑な部分は、enumのデカルト積です。 – Jarod42
私はIntTからint型への特性マッピングを見ることができますが、コンパイル時にのみ可能ですか?製品の列挙型タプルのベクトルがあったとしても、それをループして 'map.insert({i、SomeOperation()>。type、Trait ()>型を追加することはできませんでした。 ()>。type>()}) '正しい? –
experquisite
なぜ、 'std :: function'はvtableの検索よりもずっと高速になると思いますか? vtables(あなたが知っている限り)がヒープ/フリーストアの割り当てを必要とするのに対し、 'std :: function'はパックドメモリで動作できるのでしょうか?vtableは極端な場合に特有のレイアウトを持つ関数のテーブルへのポインタに過ぎません。第二に、あなたのソリューションについて何が面倒なのですか? "これは面倒なこと"は "これはうまくいかない"のようなものです。それらの構造体を手作業で入力しているという問題はありますか? – Yakk