ユニオンを作成する必要がありますが、ユニオンの 2 つのメンバーが同じタイプになるため、それらを識別する方法が必要です。たとえば、OCaml では次のようになります。
type A =
| B of int
| C of float
| D of float
Boost.Variant はこのケースをサポートしていないようですが、それをサポートする既知のライブラリはありますか?
現時点ではできませんが、C++ 17 の実装ではstd::variant
幸いなことにそれが可能です。
バリアントは、同じ型を複数回保持すること、および同じ型の異なる cv 修飾バージョンを保持することが許可されています。
ブースト バージョンとは異なり、次のようなインデックスで値を取得できます (テストされていません)。
// Construct a variant with the second value set.
variant<string, string, string> s(std::in_place_index<1>, "Hello");
// Get the second value.
string first = std::get<1>(s);
Michael Park は、C++17 の の C++14 実装をstd::variant
作成しました。
C++ コードは次のとおりです。
重複する型を含むことができるという点で、真にタグ付き共用体です。優れた機能の 1 つは、タグを列挙できることです。したがって、タグには意味のある名前を付けることができます。
残念ながら、実装では再帰継承が使用されているため、コンパイル時間のコストはかなり悪いと思います。OTOH、おそらくコンパイラは最終的にコンパイル時間のコストを削減する方法を見つけ出すでしょう。
OTOH、boost::variant に固執したい場合は、Mark B が提案したように、型をラップできます。fusion::pair<mpl::int_<tag>,T_tag>
ただし、マーク B の記述的なクラス名の代わりに、ある程度の検討が必要ですが、 source のwhere T_tag
is the tag-th 要素を使用できますfusion::vector
。IOW:
variant
< fusion::pair<mpl::int_<1>,T1>
, fusion::pair<mpl::int_<2>,T2>
...
, fusion::pair<mpl::int_<n>,Tn>
>
融合のドキュメントとして:
http://www.boost.org/doc/libs/1_55_0/libs/fusion/doc/html/fusion/support/pair.html
たとえば、fusion::pair
2 番目のテンプレート引数にのみスペースを割り当てます。したがって、これは よりも多くのスペースを必要としませんboost::variant<T1,T2,...,Tn>
。
HTH。
-よろしく、ラリー