1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
|
#include <iostream>
#include <tuple>
template < typename... FN > struct multi_call
{
multi_call() = delete ;
explicit multi_call( FN... fn ) : functions{ fn... } {}
template < typename... ARGS >
void operator() ( ARGS&&... args ) const
{
call< void, std::tuple_size< decltype(functions) >::value - 1, std::tuple<FN...> >
{ functions, std::forward<ARGS>(args)... } ;
}
private:
const std::tuple<FN...> functions ;
/////////// helper template to extract tuple elements and call ////////////
template < typename, std::size_t, typename... > struct call ;
template < typename T, std::size_t N, typename... ITEMS >
struct call< T, N, std::tuple<ITEMS...> > : call< T, N-1, std::tuple<ITEMS...> >
{
template < typename... ARGS >
call( const std::tuple<ITEMS...>& tup, ARGS&&... args )
: call< T, N-1, std::tuple<ITEMS...> >( tup, std::forward<ARGS>(args)... )
{ std::get<N>(tup)( std::forward<ARGS>(args)... ) ; }
};
template < typename T, typename... ITEMS >
struct call< T, 0, std::tuple<ITEMS...> >
{
template < typename... ARGS >
call( const std::tuple<ITEMS...>& tup, ARGS&&... args )
{ std::get<0>(tup)( std::forward<ARGS>(args)... ) ; }
};
};
int main()
{
const multi_call mc
{
[] ( int, int, int ) { std::cout << "one\n" ; },
[] ( double, short, char ) { std::cout << "two\n" ; },
[] ( long, double, int ) { std::cout << "three\n" ; },
[] ( char, char, char ) { std::cout << "four\n" ; }
};
mc( 'a', 'b', 'c' ) ;
}
|