snippet.cpp
//
// Created by allspark on 4/14/19.
//
 
#include <tuple>
#include <variant>
#include <iostream>
 
template<typename B>
struct VariantVisitor : B
{
  VariantVisitor(B&& b) : B(std::move(b)) {}
  VariantVisitor(B const& b) : B(b) {}
 
  using B::operator();
 
  template<typename...VS>
  void operator()(std::variant<VS...> const& v)
  {
    std::visit(static_cast<B&>(*this), v);
  }
};
 
template<typename VISITOR, std::size_t... IS, typename ... TS>
void my_visit_impl(VISITOR&& visitor, std::tuple<TS...> const& tuple, std::index_sequence<IS...>)
{
  VariantVisitor<std::remove_reference_t<VISITOR>> new_v(std::forward<VISITOR>(visitor));
 
  (new_v(std::get<IS>(tuple)),...);
}
 
template<typename VISITOR, typename... TS>
void my_visit(VISITOR&& visitor, std::tuple<TS...> const& tuple)
{
  return (my_visit_impl(std::forward<VISITOR>(visitor), tuple, std::make_index_sequence<sizeof...(TS)>{}));
}
 
int main()
{
  std::tuple<int, int, std::variant<int, double>> v{1, 5, 42};
//  std::tuple<std::string, std::string_view> v{"hello", "world"};
 
 
  my_visit([](auto const& value){
    std::cout << typeid(decltype(value)).name() << '\n';
    std::cout << "value: " << value << '\n';
    }, v);
}