Skip to content

Instantly share code, notes, and snippets.

@elbeno
Last active July 27, 2017 22:17
Show Gist options
  • Save elbeno/e1a64b2bce09440dc1fa65176a00df6f to your computer and use it in GitHub Desktop.
Save elbeno/e1a64b2bce09440dc1fa65176a00df6f to your computer and use it in GitHub Desktop.
Vittorio's overload_set
#pragma once
#include <type_traits>
#include <utility>
#if __cplusplus >= 201703L
// C++17 has variadic using
template <typename... Fs>
struct overload_set : Fs...
{
using Fs::operator()...;
};
#else
// C++14 has to do template recursion
template <typename... Fs> struct overload_set;
// Base case
template <typename F>
struct overload_set<F> : F
{
using F::operator();
template <typename FF>
overload_set(FF&& f)
: F{std::forward<FF>(f)}
{}
};
// Recursive case
template <typename F, typename... Fs>
struct overload_set<F, Fs...> : F, overload_set<Fs...>
{
using F::operator();
using overload_set<Fs...>::operator();
template <typename FF, typename... FFs>
overload_set(FF&& f, FFs&&... rest)
: F{std::forward<FF>(f)}
, overload_set<Fs...>{std::forward<FFs>(rest)...}
{}
};
#endif
template <typename... Fs>
inline auto overload(Fs&&... fs)
{
return overload_set<std::remove_reference_t<Fs>...>(
std::forward<Fs>(fs)...);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment