Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save qrealka/52777d4116518aa1e6bc5e292b388dc7 to your computer and use it in GitHub Desktop.
Save qrealka/52777d4116518aa1e6bc5e292b388dc7 to your computer and use it in GitHub Desktop.
Any, variant and lambda visitor
#include <boost/variant.hpp>
#include <boost/spirit/home/support/detail/hold_any.hpp>
#include <iostream>
#include <type_traits>
using Any = boost::spirit::hold_any;
template<typename ...> struct VariantAnyCast;
template<class T, class ... Rest>
struct VariantAnyCast<T, Rest...>
{
template<typename ... V>
void operator()(boost::variant<V ...>& v, Any const& any) const
{
any.type() == typeid(T) ? (v = boost::spirit::any_cast<T>(any), 0)
: (VariantAnyCast<Rest...>{}(v, any), 0);
}
};
template<>
struct VariantAnyCast<>
{
template<typename ...T>
void operator()(T&& ...) const
{
//throw bad any cast
throw std::runtime_error{"bad variant cast"};
}
};
template<typename ...T>
auto variant_any_cast(Any const& any)
{
boost::variant<T...> result{};
VariantAnyCast<T...>{}(result, any);
return result;
}
int main()
{
auto v = variant_any_cast<int,double>(Any{1.2});
boost::apply_visitor([](auto const& x){
std::cout << x << std::endl;
}, v);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment