I wrote something more general – some pseudocode showing what can it do:
auto funcs = mk<TupleOfFunctions>(f, g, h); // f, g, h -- callables
// mk is my helper function, I defined it in # Usage # section
funcs(arg) == h(g(f(arg))); // similiar to pipe in shell
// echo arg | f | g | h
In plain english, it's template of class. It's constructor that takes any amount of callables. Calling it's instance will return argument transformed by every function which constructor received.
And, because it's callable, you should be able to pass it to for_each
.
Code
#include <utility>
// 1 //
template <typename T, typename U>
struct PairOfFunctions: std::pair<T, U> {
using std::pair<T, U>::pair;
template <typename... Args>
auto operator() (Args&&... args) {
return std::pair<T, U>::second(std::pair<T, U>::first(args...));
}
};
template<typename...>
struct TupleOfFunctions;
// 2 //
template<typename T, typename... U>
struct TupleOfFunctions<T, U...>: PairOfFunctions<T, TupleOfFunctions<U...> >{
using PairOfFunctions<T, TupleOfFunctions<U...> >::PairOfFunctions;
TupleOfFunctions(T t, U... u):
PairOfFunctions<T, TupleOfFunctions<U...> >(
t,
TupleOfFunctions<U...>(u...)
)
{}
};
// 3 //
template<>
struct TupleOfFunctions<>{
template <typename T>
T operator() (T t) { // probably not optimal, too lazy to overload
return t;
}
};
Some explanation
PairOfFunctions
– subclass of pair:
mk<PairOfFunctions>(f, g)(arg) == g(f(arg));
TupleOfFunctions
– Generalization of PairOfFunctions
, takes one or more callables.
TupleOfFunctions<>
: special case – takes no functions, returns copy of argument.
Usage
My example is dumb, feel free to replace it.
// My universal helper
template<template <typename...> class T, typename... Args>
auto mk(Args... args){
return T<Args...>{args...};
}
int main()
{
auto a = mk<TupleOfFunctions>(
[](int a) {return a*2;},
[](int a) {return a + 10;},
[](int a) {return a / 2;}
);
std::cout << a(4) << '\n'; // (4 * 2 + 10) / 2
}
See it working online