I would like to visit "recursive" std::variantusing lambdas functions and overload creation functions (like boost::hana::overload).
Suppose I have a type option my_variantthat can store one int, a floator vector<my_variant>:
struct my_variant_wrapper;
using my_variant =
std::variant<int, float, std::vector<my_variant_wrapper>>;
struct my_variant_wrapper
{
my_variant _v;
};
(I use a wrapper class my_variant_wrapperto determine the type of a variant recursively.)
I want to recursively visit the option of printing different things depending on the types stored. Here's a working example using a visitor based on struct:
struct struct_visitor
{
void operator()(int x) const { std::cout << x << "i\n"; }
void operator()(float x) const { std::cout << x << "f\n"; }
void operator()(const std::vector<my_variant_wrapper>& x) const
{
for(const auto& y : x) std::visit(*this, y._v);
}
};
A call std::visitwith the above client displays the desired result:
my_variant v{
std::vector<my_variant_wrapper>{
my_variant_wrapper{45},
std::vector<my_variant_wrapper>{
my_variant_wrapper{1}, my_variant_wrapper{2}
},
my_variant_wrapper{33.f}
}
};
std::visit(struct_visitor{}, v);
lambdas, boost::hana::overload boost::hana::fix.
fix Y-combinator, lambdas . (. .)
, :
namespace bh = boost::hana;
auto lambda_visitor = bh::fix([](auto self, const auto& x)
{
bh::overload(
[](int y){ std::cout << y << "i\n"; },
[](float y){ std::cout << y << "f\n"; },
[&self](const std::vector<my_variant_wrapper>& y)
{
for(const auto& z : y) std::visit(self, z._v);
})(x);
});
:
boost::hana::fix , std::variant.
boost::hana::fix , , , .
boost::hana::overload my_variant , struct_visitor.
self lambda_visitor const std::vector<my_variant_wrapper>& .
bh::overload(...)(x) .
, wandbox, lambda_visitor , - :
...
/usr/local/boost-1.61.0/include/boost/hana/functional/fix.hpp:74:50: : 'main():: [ : 2 = boost:: hana:: fix_t > ; auto: 3 = int] ' ' auto ' {return f (fix (f), static_cast (x)...); }
...
, boost::hana::fix:
auto lambda_visitor = bh::overload(
[](int y){ std::cout << y << "i\n"; },
[](float y){ std::cout << y << "f\n"; },
[](const std::vector<my_variant_wrapper>& y)
{
for(const auto& z : y) std::visit(lambda_visitor, z._v);
});
std::visit(lambda_visitor, v);
: 'lambda_visitor' 'auto' for (const auto & z: y) std:: visit (lambda_visitor, z._v);
? fix, overload lambdas?
, lambda_visitor "" struct_visitor, , fix.