Skip to content

Instantly share code, notes, and snippets.

@hryniuk
Created April 6, 2017 22:54
Show Gist options
  • Save hryniuk/575ec04b9e4726051baece058261ab07 to your computer and use it in GitHub Desktop.
Save hryniuk/575ec04b9e4726051baece058261ab07 to your computer and use it in GitHub Desktop.
Metafun with functors
#include <iostream>
#include <tuple>
template<typename Tuple, int Size, int Index=0>
struct Apply
{
void operator()(Tuple t) const
{
std::cout << std::get<Index>(t) << std::endl;
Apply<Tuple, Size, Index + 1>().operator()(t);
}
};
template<typename Tuple, int Size>
struct Apply<Tuple, Size, Size>
{
void operator()(Tuple) const { }
};
template<typename Func, typename T>
void g(Func&& f, T a)
{
std::cout << f(a) << std::endl;
}
template<typename Func, typename T, typename... Args>
void g(Func&& f, T a, Args... args)
{
std::cout << f(a) << std::endl;
g(std::forward<Func>(f), std::forward<Args>(args)...);
}
using KT = std::tuple<double, int, char>;
template<typename Tuple, int Size, int Index=0>
struct ApplyT
{
using type = typename std::tuple_element<Index, Tuple>::type;
using next_apply = ApplyT<Tuple, Size, Index + 1>;
template<typename T>
auto operator()(T&& a) const -> T
{
next_apply()(type()(a));
}
};
template<typename Tuple, int Size>
struct ApplyT<Tuple, Size, Size>
{
template<typename T>
T operator()(T&& a) { return a; }
};
struct A
{
int operator()(int a)
{
return 3 * a;
}
};
struct B
{
int operator()(int a)
{
return 10 * a;
}
};
int main()
{
auto t = std::make_tuple(std::string("hello world"), 1, 3.214);
Apply<decltype(t), std::tuple_size<decltype(t)>::value, 0> a;
a(t);
a(std::make_tuple(std::string("hello world"), 1, 3.214));
g([](auto k){return k * 3;}, 3, 2.0, 1u);
using funcs = std::tuple<A, B>;
ApplyT<funcs, std::tuple_size<funcs>::value> b;
std::cout << b(10) << std::endl;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment