Мне нужно создать профсоюз, но 2 члена профсоюза будут иметь один и тот же тип, поэтому мне нужен способ их идентификации. Например, в OCaml:
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 :: варианта, вы можете обернуть типы,
как предложил Марк Б. Однако вместо описательных имен классов Марка Б
которые требуют некоторой мысли, вы могли бы использовать fusion::pair<mpl::int_<tag>,T_tag>
где T_tag
является тегом-ом элемента в источнике fusion::vector
, IOW:
variant
< fusion::pair<mpl::int_<1>,T1>
, fusion::pair<mpl::int_<2>,T2>
...
, fusion::pair<mpl::int_<n>,Tn>
>
Как документы Fusion:
http://www.boost.org/doc/libs/1_55_0/libs/fusion/doc/html/fusion/support/pair.html
сказать, fusion::pair
выделяет место только для второго аргумента шаблона; следовательно,
это не должно занимать больше места, чем boost::variant<T1,T2,...,Tn>
,
НТН.
-С уважением,
Larry
Вы не можете в данный момент, но C ++ 17 реализация 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);
Майкл Парк написал реализация C ++ 14 C ++ 17 std::variant
.