ネットワーク経由で送信できるタイプのリストがあります。次の例を見てください。
enum types {
E_T1,
E_T2,
E_T3,
E_T4
};
class E_T1 {...}
これで、各タイプに対応するクラスのリストができました。たとえば、それぞれが、class E_T2 {...}
などとして宣言されているとします。
それらは共通の基本クラスから派生しておらず、そうすることはできません。各クラスには、ネットワーク経由で送信されるデータを使用して呼び出す必要のある検証メソッドがあります。クライアントは、メッセージタイプに対応するデータD
とIDを送信します。タイプに対応するオブジェクトを取得する必要があります。必要に応じてC++0x機能を使用できます。
私がこれまでに試したことはtypes
、に関連するオブジェクトのtypedefを保持する、に特化したテンプレートを使用することです。テンプレートパラメータはコンパイル時定数である必要があるため、これは明らかにばかげた考えでした。そのため、何かを実行することgetType<data.id()>::type
はできません。
次に、Boost.Variantを使用して、次のような一般的なリターナブルタイプを取得しようとしました(デバグのために実行時に登録されたタイプを反復処理するためにmplベクトルを使用):
template <typename C>
struct getType() {
typedef C type;
}
typedef boost::mpl::vector<
getType<E_T1>,
getType<E_T2>,
getType<E_TX>...
> _types;
typedef boost::make_variant_over<_types>::type _type;
//use a map to store each type <-> id
boost::unorderd_map<types, _type> m;
m[E_T1] = getType<E_T1>();
m[data.id()]::type x; //<- access type, can now call x.validate(data)
これに伴う問題は、デフォルトでバリアントごとに20エントリに制限されていることです。これは上書きできますが、私が理解したことから、タイプごとのオーバーヘッドを考慮する必要があり、ここでは数千のタイプについて話します。
また、boost.anyを試しましたが、タイプ情報が保持されていないため、これも問題外です。これをエレガントに解決する方法について、誰か良いアイデアはありますか?型を処理するときはいつでも1kのswitchステートメントを書く必要がないものを探しています。
すべてのタイプがコンパイルタイプになりました。対応するIDについても同じです。Id->タイプの解決は実行時に行う必要があります。
よろしくお願いします、ロビン。