#include <iostream>
#include <string>
#include <stdexcept>
#include <functional>
#include <utility>

template <typename... Args, typename F, size_t... ints>
void match_impl(size_t n, const std::tuple<Args...>& t, const F& f, std::integer_sequence<size_t, ints...> int_seq)
{
  std::function<void()> fs[sizeof...(Args)] = {
    [&]() { f(std::get<ints>(t)); }...
  };

  fs[n]();
}

template <typename... Args, typename F>
void match(size_t n, const std::tuple<Args...>& t, const F& f )
{
  match_impl(n, t, f, std::index_sequence_for<Args...>{});
}

int main() {
  auto tuple = std::make_tuple(1, '2', 3.33, std::string("abcdef"));

  int tuple_index = 3;

  auto visitor = [](const auto& tuple_value) {
    std::cout << tuple_value << std::endl;
  };

  match(tuple_index, tuple, visitor);

  return 0;
}