2011-02-07 21 views
2

私は、任意のユーザ定義クラスのインスタンスを保持するバリアント型が必要です。だから私は、void *型を使用します。boost :: variantとvoid *ポインタ

typedef boost::variant<void*, int, float, std::string> Tvariant; 

私はマップとラッパークラスを作成しました:使用方法の

typedef std::map<std::string, Tvariant> Tvalues; 

例:

int x = 123; 
attributes.set("int_var", x); 
x = attributes.get<int>("int_var"); 

MyClass* obj = new MyClass(); 
attributes.set("void*_var", obj); 
obj = static_cast<MyClass*>(attributes.get<void*>("void*_var")); 
obj = attributes.cast<MyClass*>("void*_var"); // the same 

をこのボイド2つの問題は*ありバリアントクラス:

  1. dynaへのポインタで属性をコピーするメモリが割り当てられていると危険でエラーが発生しやすくなります。
  2. ユーザーは、static_cast void *をMyClass *ではなくWrongClass *にできます。それはコンパイルされますが、結果は予測されません。

考えられる解決策:

  1. 利用ブースト:: shared_ptrの<無効*>。
  2. std::map<void*, typeid> typeid_mapにすべてのvoid *値(追加時)のtypeidを覚えておいてください。ユーザーがvoid * valueを要求し、それをTClass *にキャストしたら、アサーション:assert(typeid_from_typeid_map == typeid(TClass*))を評価しましょう。

質問
1.任意のユーザ定義クラスの値を保持するが、他の解決策はありますか?
2.上記の問題の解決策をお勧めしますか?

答えて

6

Boost::Anyを見ましたか?これは、タイプのキャスティングの時間の知識をコンパイルしながら、実際にはAnyを介してどのタイプを隠しているかを示します。

+0

はい、しかしboost :: anyはコンパイル時のチェックを提供せず、boost :: variantよりも遅いです。 boost :: anyは、任意の値をユーザー定義のクラスにキャストするときに型の安全性を提供しますか? –

+0

@topright既にBoostを使用しているので、boost :: anyは行く方法のようです。 – karlphillip

+2

@topright: 'boost :: any'は実行時の型チェックを提供し、' any_cast'は検索する型を指定する必要があります。 'Myclass * c = any_cast (myMap [" myClassObj "])'、型について間違っていた場合は 'bad_any_cast'をスローします。マップ内の値を調べるので、 'boost :: any'のオーバーヘッドがあなたに関係するのではないかと疑います。構文上非常にきれいで、非常に安全です。 –

関連する問題