Skip to content

Instantly share code, notes, and snippets.

@LB--
Created March 22, 2018 03:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save LB--/82cd3947fc98a9481ff14bac23b412a0 to your computer and use it in GitHub Desktop.
Save LB--/82cd3947fc98a9481ff14bac23b412a0 to your computer and use it in GitHub Desktop.
I'm working on an implementation of std::overload. This version requires that you specify the argument types for the callables, but it works on anything that can be called. Also handles const-correctness thanks to SFINAE. If you comment out line 69, GCC optimizes it to `return 10;`: https://godbolt.org/g/2GFgFX
#include <variant>
namespace impl
{
template<typename T, typename Callable>
struct Overload
{
Callable callable;
auto operator()(T &t) noexcept(noexcept(callable(t)))
{
return callable(t);
}
auto operator()(T const &t) noexcept(noexcept(callable(t)))
{
return callable(t);
}
auto operator()(T &t) const noexcept(noexcept(callable(t)))
{
return callable(t);
}
auto operator()(T const &t) const noexcept(noexcept(callable(t)))
{
return callable(t);
}
};
template<typename... Bases>
struct Overloads final
: Bases...
{
using Bases::operator()...;
};
}
template<typename... Types, typename... Callables>
auto overload(Callables &&... callables) noexcept(noexcept(impl::Overloads<impl::Overload<Types, Callables>...>{callables...}))
{
static_assert(sizeof...(Types) == sizeof...(Callables));
return impl::Overloads<impl::Overload<Types, Callables>...>{callables...};
}
int main()
{
using variant_t = std::variant<char, short, int, double>;
short v = 0;
auto visitor = overload<char, short, int, double>
(
[](char const v)
-> int
{
return v+1;
},
[](short v)
-> int
{
return v+10;
},
+[](int &v)
-> int
{
return v+100;
},
[=](double) mutable
-> int
{
return v += 1000;
}
);
v = visitor(v);
variant_t var {v};
v += std::visit(visitor, var);
return v;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment