Skip to content

Instantly share code, notes, and snippets.

@DieHertz
Last active August 29, 2015 14:05
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 DieHertz/635c56dc82c3084fa0ea to your computer and use it in GitHub Desktop.
Save DieHertz/635c56dc82c3084fa0ea to your computer and use it in GitHub Desktop.
#include <type_traits>
#include <utility>
template<typename R, typename... Args>
struct function_ptr_wrapper {
using type = R(*)(Args...);
type function;
function_ptr_wrapper(type function) : function{function} {}
R operator()(Args... args) const { return (*function)(args...); }
};
/// wrap function pointers, forward functional objects as is
template<typename T> struct function_helper { using type = T; };
template<typename R, typename... Args> struct function_helper<R(*)(Args...)> {
using type = function_ptr_wrapper<R, Args...>;
};
template<typename R, typename... Args> struct function_helper<R(Args...)> {
using type = function_ptr_wrapper<R, Args...>;
};
template<typename T> using function_helper_t = typename function_helper<typename std::remove_reference<T>::type>::type;
/// inherit from each callable entity, thus received their operator() implementations
template<typename... T>
struct overloaded_function : function_helper_t<T>... {
template <typename... U>
overloaded_function(U&&... u) : function_helper_t<U>(std::forward<U>(u))... {}
};
/// type-deduction helper
template<typename... T> overloaded_function<T...> make_overloaded(T&&... t) {
return overloaded_function<T...>{std::forward<T>(t)...};
}
#include <iostream>
void fun(const double) { std::cout << "called with double" << std::endl; }
int main() {
const auto f = make_overloaded(
[] (const int) { std::cout << "called with int" << std::endl; },
[] (const float) { std::cout << "called with float" << std::endl; },
fun);
f(1), f(1.0f), f(1.0);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment