Это просто не поддерживается в стандартной библиотеке по любой причине.std::variant
был очень длинный, очень спорный процесс.Может быть, этот конкретный аспект просто не был в чьем-то списке?
Единственная возможная техническая проблема при добавлении такого конвертирующего конструктора и конвертирующего оператора присваивания - это странные патологические взаимодействия с текущим.Прямо сейчас, у variant<Ts...>
есть конструктор, принимающий T&&
, для которого он пытается выбрать Ts
.Это может привести к конфликту, и вам придется ответить на вопрос о том, что вы хотите, чтобы произошло здесь:
struct X { X(variant<int>); };
variant<int> v = 42;
variant<int, X> w = v;
В настоящее время это допустимо, и w
содержит X
, построенный из v
.Хотели бы вы, чтобы это изменилось и чтобы w
удерживал int
42
?
На данный момент вам просто нужно сделать это вручную:
template <typename To, typename From>
To variant_cast(From&& from) {
return std::visit(
[](auto&& elem) { return To(std::forward<Elem>(elem)); },
std::forward<From>(from));
}
Синтаксис не будет таким приятным (и приведенная выше реализация не является SFINAE-дружественной), но он получает работусделано:
using V2 = variant<int, char>;
auto v2 = variant_cast<V2>(v1);
v2 = variant_cast<V2>(v1);
v2 = variant_cast<V2>(std::move(v1));
// at least this one is stil easy :-)
auto v3 = std::move(v2);