我需要創建聯合,但聯合的兩個成員具有相同類型,因此我需要一種方法來識別它們。例如在OCaml中:多次使用相同類型在C++中標記的聯合(又名變體)
type A =
| B of int
| C of float
| D of float
Boost.Variant似乎不支持這種情況,是否有支持這種情況的已知庫?
我需要創建聯合,但聯合的兩個成員具有相同類型,因此我需要一種方法來識別它們。例如在OCaml中:多次使用相同類型在C++中標記的聯合(又名變體)
type A =
| B of int
| C of float
| D of float
Boost.Variant似乎不支持這種情況,是否有支持這種情況的已知庫?
如果你想做到這一點,我想你最好的選擇是包裝相同,但是,不同類型成一個結構,然後讓升壓變訪問正確的一個:
struct Speed
{
float val_;
};
struct Darkness
{
float val_;
};
你可能能夠使用BOOST_STRONG_TYPEDEF
自動執行此操作,但我不確定它是否能夠生成合法使用的類型(儘管在變體中它可能沒問題)。
的C++代碼在這裏:
是真正的,因爲它可以包含重複類型的一個標籤聯合。一個不錯的功能 是標籤可以枚舉;因此,標籤可以具有有意義的名稱。
不幸的是,編譯時間成本非常糟糕,我想,因爲實現 使用遞歸繼承。 OTOH,也許編譯器最終會找出一種方法來減少編譯時間成本。
OTOH,如果你想堅持使用boost :: variant,你可以按照Mark B的建議包裝 。但是,代替Mark B的描述性類名稱 需要一些考慮,您可以使用fusion::pair<mpl::int_<tag>,T_tag>
其中T_tag
是源fusion::vector
中的第個元素。督察:
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
只分配了第二個模板參數空間;因此, 這應該不會比boost::variant<T1,T2,...,Tn>
佔用更多空間。
HTH。
-regards, 拉里
你不能在此刻卻C++17's implementation of std::variant
還好允許它:
一個變體被允許持有相同類型不止一次,並持有不同品種合格相同類型的版本。
不像增壓版本,您可以通過索引獲取值,像這樣(未測試):
// 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);
爲什麼兩個相同的'type'?任何時候只能使用一個工會會員。 – hmjd
我知道,但有些情況下,即使他們具有相同的基礎類型,您也想對成員進行破壞。一個小例子是一個Expr類型,它有2個成員IntConst int和IntMutable int。 – maattdd
但是必須有某個其他標誌(包含'struct'或'class')指示哪個聯合成員是_active_?這可以用來提供額外的必要含義。 – hmjd