2012-02-02 2 views
8

any変数を元のタイプにキャストする必要があります。 私はこれを実行する必要があります。Boost.Any元のタイプを取得する

int i = 10; 
any a(i); 
int& i2 = any_cast<int &>(a); 

をしかし、私がしたいことany変数に型店舗。そして私はこれを書いています:

int i = 10; 
any a(i); 
a::type_value& i2 = any_cast<a::type_value &>(a); // there is no actually type_value 

どうすればいいですか?または、どのようにして元のタイプをany変数から抽出できますか? Boost.variantも便利です。

もし私がそれを行うことができないなら、私はC++のテクニックやライブラリがこの問題を解決する関数を介して型を保存して得ることができるかという別の質問をします。

+1

Boost.Anyでこれを行うのは簡単ではないので、代わりにBoost.Variantを使用することが基本的な答えになります。 – ildjarn

+2

*なぜ*これを行う必要がありますか? – GManNickG

答えて

15

C++は、であり、静的にはです。 boost::anyのタイプはランタイムの値です。任意の特定のanyは任意のタイプを持つことができます。それはちょっとのポイントです。

コンパイル時間の値でなければならないため、any::type_valueはありません。 anyは実行時構成です。

この考えてみましょう:どのような種類の

void TakeAnAny(boost::any a) 
{ 
    a::type_value& i2 = any_cast<a::type_value &>(a); 
} 

any::type_valueあるの? TakeAnAnyと電話番号のいずれかをと呼ぶのは合法です。 any::type_valueが縮小できる単一のコンパイル時型はありません。したがって、コンパイラが型を決定する方法はありません。 C++は静的に型付けされているので、あなたはホースしています。

いずれのタイプの最終的な目的はタイプ消去です。私はいくつかの価値があります。そして私はそれを他の機能に渡したいと思います。このプロセスは、いくつかの異なる通信レイヤーを経由します。しかし、私は必ずしも、それらの異なるレイヤーのすべてが、私が使っているタイプを正確に知ることを望んでいません。私はタイプを知るために自分と私の目的地が必要です。あなたはanyにそれを貼り付け、あなたは大丈夫です。他の誰もがanyを見るだけで、どちらがラップするのかを知っています。

このプロセスは、送信元と宛先の両方が実際の値の型を認識しているためにのみ機能します。タイプがわからない場合は、anyを使用するべきではありません。 anyの目的は、そこに座って、それを可能な種類の束にキャストする機能を持たない(それは、boost::variantが対象です)。目的は、関数の署名から型を消去することです。

これにより、一般的なメッセージや信号などが可能になります。イベントハンドラをシステムに登録します。あなたはパラメータとしてanyを取るイベントを発生させます。イベントを発生させる人は、 "MouseClick"イベントが常にvec2をそのパラメータとして取ることを知っています。したがって、すべての "MouseClick"ハンドラはvec2にキャストします。 「KeyPress」イベントはint32_tになります。そのハンドラーはそのタイプにキャストします。その他誰もが実際にどのようなタイプを知っている。

void*でこれを行う必要がありました。問題は所有者の問題があることです(anyは値ですが、void*はポインタです)。また、void*はタイプが消去されているため、キャストが正しいかどうかを確認する方法がありません。 anyは実際には&値の安全なタイプvoid*です。 に間違ったタイプにキャストすることができなくなります。

あなたは本当にしたくないですany。あなたのユースケースはvariantのいずれかになりません。あなたが望むようなものはテンプレートです。これは別の種類のもので、あなたが本当に望んでいることを実行できるようにします。特定の型を使用できる関数を持ちますが、その型が何であるかを正確に知ることができます。

もちろん、テンプレートには独自の制限があります。

1

あなたは、あなたが知っている、あなたがに対処したいタイプに対処するstd::function<void(boost::any const&)>オブジェクトにstd::type_infoのマップを使用することができます:あなたはa.type()を使用してマップ内のエントリを検索し、どのように知っているだろう、対応する関数を呼び出します議論を扱う。

+2

もし彼らが扱うことになるタイプを知っているなら、なぜBoost.AnyをBoostの代わりに使うのでしょうか?最初は変わりますか? – ildjarn

+1

これは簡単なタイプのようです。また、 'boost :: any'を引数とし、最終的に何らかの形で' boost :: any'が返される関数を呼び出すインタフェースがあるかもしれません。例えば、任意の情報を保持するためにオブジェクトに 'boost :: any'を付けるのは合理的なことであり、クラスのユーザは彼がどのタイプを添付するかをよく知っているようです。 –

+0

特定のシナリオを考えれば、私は 'boost :: any <>'が適切かもしれないことに同意します。結局のところ、図書館は理由のために存在する。しかし、どういうわけか私はOPがその特定のシナリオにあるとは思っていません。OPには具体的な理由がない限り、Boost.Variantに投票します。 ; - ] – ildjarn

関連する問題