// Using a factory functions avoids default constructibility of the variant
auto factory = [](auto i)
{
using VX = std::variant<X0,X1,X2>;
if (i == 0)
return VX(std::in_place_type_t<X0>());
else if (i == 1)
return VX(std::in_place_type_t<X1>());
else
return VX(std::in_place_type_t<X2>());
};
// Cast reference to variant<T0,...> to common
// polymorphic base class T of T0, ... . T should
// be a template parameter, but since we're at block
// level T=X is hardwired.
auto commonBaseCast = [](auto& x) -> decltype(auto) {
return std::visit([](auto& x) -> decltype(auto){
return dynamic_cast<X&>(x);
}, x);
};
auto x = factory(i);
pX = &commonBaseCast(x);
The commonBaseCast could also be replace by single line
pX = std::visit([](auto& x){ return dynamic_cast<X*>(&x);}, x);
but using a named function for the cast nicely documents the intend.