Multiple variadic templates function [closed]












0















Assume I have two functions f1() and f2() defined as follow:



template<class ... Types> void f1(Types ... args1)
template<class ... Types> void f2(Types ... args2)


Now I want to create a third function f3() which takes input f1() and f2(), how do I define f3() with both args1... and args2...?



template<class F1, class F2> void f3(F1 f1, F2 f2) {
f1(); // how do I call f1? I need to pass in the args...
}









share|improve this question















closed as unclear what you're asking by Neil Butterworth, πάντα ῥεῖ, genpfault, Jarod42, Billal Begueradj Jan 3 at 6:19


Please clarify your specific problem or add additional details to highlight exactly what you need. As it's currently written, it’s hard to tell exactly what you're asking. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.



















  • Could you explain your expected behavior? And it's confusing that you use the names f1 and f2 in two ways - do you want f3 to call the function passed to it, or the function actually named f1 declared above? How are these two things related?

    – aschepler
    Jan 2 at 23:47











  • @aschepler what max66 added answers my question well. I have two functions: f1 and f2, both are variadic templates functions. Now I want to pass them to a new function, f3. At the same time, I need to pass the params for f1 and f2 to f3 as well. If f1 and f2 share the same params, it's easy. But for my case they don't.

    – WhatABeautifulWorld
    Jan 2 at 23:53
















0















Assume I have two functions f1() and f2() defined as follow:



template<class ... Types> void f1(Types ... args1)
template<class ... Types> void f2(Types ... args2)


Now I want to create a third function f3() which takes input f1() and f2(), how do I define f3() with both args1... and args2...?



template<class F1, class F2> void f3(F1 f1, F2 f2) {
f1(); // how do I call f1? I need to pass in the args...
}









share|improve this question















closed as unclear what you're asking by Neil Butterworth, πάντα ῥεῖ, genpfault, Jarod42, Billal Begueradj Jan 3 at 6:19


Please clarify your specific problem or add additional details to highlight exactly what you need. As it's currently written, it’s hard to tell exactly what you're asking. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.



















  • Could you explain your expected behavior? And it's confusing that you use the names f1 and f2 in two ways - do you want f3 to call the function passed to it, or the function actually named f1 declared above? How are these two things related?

    – aschepler
    Jan 2 at 23:47











  • @aschepler what max66 added answers my question well. I have two functions: f1 and f2, both are variadic templates functions. Now I want to pass them to a new function, f3. At the same time, I need to pass the params for f1 and f2 to f3 as well. If f1 and f2 share the same params, it's easy. But for my case they don't.

    – WhatABeautifulWorld
    Jan 2 at 23:53














0












0








0








Assume I have two functions f1() and f2() defined as follow:



template<class ... Types> void f1(Types ... args1)
template<class ... Types> void f2(Types ... args2)


Now I want to create a third function f3() which takes input f1() and f2(), how do I define f3() with both args1... and args2...?



template<class F1, class F2> void f3(F1 f1, F2 f2) {
f1(); // how do I call f1? I need to pass in the args...
}









share|improve this question
















Assume I have two functions f1() and f2() defined as follow:



template<class ... Types> void f1(Types ... args1)
template<class ... Types> void f2(Types ... args2)


Now I want to create a third function f3() which takes input f1() and f2(), how do I define f3() with both args1... and args2...?



template<class F1, class F2> void f3(F1 f1, F2 f2) {
f1(); // how do I call f1? I need to pass in the args...
}






c++ c++11 templates variadic-templates variadic-functions






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Jan 3 at 10:57









max66

38.7k74473




38.7k74473










asked Jan 2 at 21:21









WhatABeautifulWorldWhatABeautifulWorld

92511124




92511124




closed as unclear what you're asking by Neil Butterworth, πάντα ῥεῖ, genpfault, Jarod42, Billal Begueradj Jan 3 at 6:19


Please clarify your specific problem or add additional details to highlight exactly what you need. As it's currently written, it’s hard to tell exactly what you're asking. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.









closed as unclear what you're asking by Neil Butterworth, πάντα ῥεῖ, genpfault, Jarod42, Billal Begueradj Jan 3 at 6:19


Please clarify your specific problem or add additional details to highlight exactly what you need. As it's currently written, it’s hard to tell exactly what you're asking. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.















  • Could you explain your expected behavior? And it's confusing that you use the names f1 and f2 in two ways - do you want f3 to call the function passed to it, or the function actually named f1 declared above? How are these two things related?

    – aschepler
    Jan 2 at 23:47











  • @aschepler what max66 added answers my question well. I have two functions: f1 and f2, both are variadic templates functions. Now I want to pass them to a new function, f3. At the same time, I need to pass the params for f1 and f2 to f3 as well. If f1 and f2 share the same params, it's easy. But for my case they don't.

    – WhatABeautifulWorld
    Jan 2 at 23:53



















  • Could you explain your expected behavior? And it's confusing that you use the names f1 and f2 in two ways - do you want f3 to call the function passed to it, or the function actually named f1 declared above? How are these two things related?

    – aschepler
    Jan 2 at 23:47











  • @aschepler what max66 added answers my question well. I have two functions: f1 and f2, both are variadic templates functions. Now I want to pass them to a new function, f3. At the same time, I need to pass the params for f1 and f2 to f3 as well. If f1 and f2 share the same params, it's easy. But for my case they don't.

    – WhatABeautifulWorld
    Jan 2 at 23:53

















Could you explain your expected behavior? And it's confusing that you use the names f1 and f2 in two ways - do you want f3 to call the function passed to it, or the function actually named f1 declared above? How are these two things related?

– aschepler
Jan 2 at 23:47





Could you explain your expected behavior? And it's confusing that you use the names f1 and f2 in two ways - do you want f3 to call the function passed to it, or the function actually named f1 declared above? How are these two things related?

– aschepler
Jan 2 at 23:47













@aschepler what max66 added answers my question well. I have two functions: f1 and f2, both are variadic templates functions. Now I want to pass them to a new function, f3. At the same time, I need to pass the params for f1 and f2 to f3 as well. If f1 and f2 share the same params, it's easy. But for my case they don't.

– WhatABeautifulWorld
Jan 2 at 23:53





@aschepler what max66 added answers my question well. I have two functions: f1 and f2, both are variadic templates functions. Now I want to pass them to a new function, f3. At the same time, I need to pass the params for f1 and f2 to f3 as well. If f1 and f2 share the same params, it's easy. But for my case they don't.

– WhatABeautifulWorld
Jan 2 at 23:53












1 Answer
1






active

oldest

votes


















2














You can't.



Because a template functions are set of functions. And you can pass a functions, explicating the template types,



f3(f1<int, long, long>, f2<char, int>);


and not the full set of functions.



The best I can suggest is to wrap your template functions in structs



struct s1
{
template <typename ... Types>
static void f1 (Types ... args1)
{ }
};

struct s2
{
template <typename ... Types>
static void f2 (Types ... args2)
{ }
};


so you can pass to f3() s1 and s2 objects



s1  a;
s2 b;

f3(a, b);


or simply the types



f3<s1, s2>();


As suggested by Jarod42, you can also wrap f1() and f2() inside a couple of lambdas (only from C++14)



auto l1 = (auto&& ... args) { f1(std::forward<decltype(args)>(args)...); };
auto l2 = (auto&& ... args) { f2(std::forward<decltype(args)>(args)...); };

f3(l1, l2)



what I mean is when I call f3, I offer f1 and f2. I also need to pass in the params for f1 and f2. How do I do that?




But the argument for f1() and f2() are the same?
Or are two different sets?



In the first case, you can pass they as template variadic arguments; something as (following the Jarod42's suggestion)



template <typename L1, typename L2, typename ... Args>
void f3 (L1 l1, L2 l2, Args const & ... as)
{
L1(as...);
L2(as...);
}

auto l1 = (auto&& ... args) { f1(std::forward<decltype(args)>(args)...); };
auto l2 = (auto&& ... args) { f2(std::forward<decltype(args)>(args)...); };

f3(l1, l2, 1, '2', 3L, 4ULL);


If you need two different set of argument, you need to wrap the arguments in std::tuple's or something similar.



template <typename L1, typename L2, typename ... As1, typename ... As2>
void f3 (L1 l1, L2 l2, std::tuple<As1...> const & t1, std::tuple<As2...> const & t2)
{
std::apply(l1, t1);
std::apply(l2, t2);
}

auto l1 = (auto&& ... args) { f1(std::forward<decltype(args)>(args)...); };
auto l2 = (auto&& ... args) { f2(std::forward<decltype(args)>(args)...); };

f3(l1, l2, std::make_tuple(1, 2l, '3'), std::make_tuple('4', 5ull));


But take in count that std::apply() is available only from C++17: before is a little more complicated extract the arguments from the tuples.




how do I do that without c++17?




The following is a full C++14 example that unpack tuples using std::index_sequence_for and std::index_sequence



#include <tuple>
#include <iostream>
#include <type_traits>

template <typename ... Ts>
void f1 (Ts ... as)
{ std::cout << "- f1: " << sizeof...(Ts) << " arguments" << std::endl; }

template <typename ... Ts>
void f2 (Ts ... as)
{ std::cout << "- f2: " << sizeof...(Ts) << " arguments" << std::endl; }

template <typename L, typename ... Ts, std::size_t ... Is>
void f3_helper (L l, std::tuple<Ts...> const & t, std::index_sequence<Is...>)
{ l(std::get<Is>(t)...); }

template <typename L1, typename L2, typename ... As1, typename ... As2>
void f3 (L1 l1, L2 l2, std::tuple<As1...> const & t1,
std::tuple<As2...> const & t2)
{
f3_helper(l1, t1, std::index_sequence_for<As1...>{});
f3_helper(l2, t2, std::index_sequence_for<As2...>{});
}

int main()
{
auto l1 = (auto && ... args)
{ f1(std::forward<decltype(args)>(args)...); };

auto l2 = (auto && ... args)
{ f2(std::forward<decltype(args)>(args)...); };

f3(l1, l2, std::make_tuple(1, 2l, '3'), std::make_tuple('4', 5ull));
}





share|improve this answer


























  • In this case, how do I pass in the params to f1 and f2?

    – WhatABeautifulWorld
    Jan 2 at 21:37











  • @WhatABeautifulWorld - do you mean: to fix a precise set of types of arguments?

    – max66
    Jan 2 at 21:40











  • what I mean is when I call f3, I offer f1 and f2. I also need to pass in the params for f1 and f2. How do I do that?

    – WhatABeautifulWorld
    Jan 2 at 21:42






  • 1





    @WhatABeautifulWorld - " if I don't have std::apply how do I do that?" - through std::make_index_sequence and std::index_sequence (but C++14 is required; in C++11 you have to write a substitute but isn't really difficult); give me some minutes ans I prepare an example.

    – max66
    Jan 2 at 23:28






  • 1





    @WhatABeautifulWorld - answer improved.

    – max66
    Jan 2 at 23:41


















1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









2














You can't.



Because a template functions are set of functions. And you can pass a functions, explicating the template types,



f3(f1<int, long, long>, f2<char, int>);


and not the full set of functions.



The best I can suggest is to wrap your template functions in structs



struct s1
{
template <typename ... Types>
static void f1 (Types ... args1)
{ }
};

struct s2
{
template <typename ... Types>
static void f2 (Types ... args2)
{ }
};


so you can pass to f3() s1 and s2 objects



s1  a;
s2 b;

f3(a, b);


or simply the types



f3<s1, s2>();


As suggested by Jarod42, you can also wrap f1() and f2() inside a couple of lambdas (only from C++14)



auto l1 = (auto&& ... args) { f1(std::forward<decltype(args)>(args)...); };
auto l2 = (auto&& ... args) { f2(std::forward<decltype(args)>(args)...); };

f3(l1, l2)



what I mean is when I call f3, I offer f1 and f2. I also need to pass in the params for f1 and f2. How do I do that?




But the argument for f1() and f2() are the same?
Or are two different sets?



In the first case, you can pass they as template variadic arguments; something as (following the Jarod42's suggestion)



template <typename L1, typename L2, typename ... Args>
void f3 (L1 l1, L2 l2, Args const & ... as)
{
L1(as...);
L2(as...);
}

auto l1 = (auto&& ... args) { f1(std::forward<decltype(args)>(args)...); };
auto l2 = (auto&& ... args) { f2(std::forward<decltype(args)>(args)...); };

f3(l1, l2, 1, '2', 3L, 4ULL);


If you need two different set of argument, you need to wrap the arguments in std::tuple's or something similar.



template <typename L1, typename L2, typename ... As1, typename ... As2>
void f3 (L1 l1, L2 l2, std::tuple<As1...> const & t1, std::tuple<As2...> const & t2)
{
std::apply(l1, t1);
std::apply(l2, t2);
}

auto l1 = (auto&& ... args) { f1(std::forward<decltype(args)>(args)...); };
auto l2 = (auto&& ... args) { f2(std::forward<decltype(args)>(args)...); };

f3(l1, l2, std::make_tuple(1, 2l, '3'), std::make_tuple('4', 5ull));


But take in count that std::apply() is available only from C++17: before is a little more complicated extract the arguments from the tuples.




how do I do that without c++17?




The following is a full C++14 example that unpack tuples using std::index_sequence_for and std::index_sequence



#include <tuple>
#include <iostream>
#include <type_traits>

template <typename ... Ts>
void f1 (Ts ... as)
{ std::cout << "- f1: " << sizeof...(Ts) << " arguments" << std::endl; }

template <typename ... Ts>
void f2 (Ts ... as)
{ std::cout << "- f2: " << sizeof...(Ts) << " arguments" << std::endl; }

template <typename L, typename ... Ts, std::size_t ... Is>
void f3_helper (L l, std::tuple<Ts...> const & t, std::index_sequence<Is...>)
{ l(std::get<Is>(t)...); }

template <typename L1, typename L2, typename ... As1, typename ... As2>
void f3 (L1 l1, L2 l2, std::tuple<As1...> const & t1,
std::tuple<As2...> const & t2)
{
f3_helper(l1, t1, std::index_sequence_for<As1...>{});
f3_helper(l2, t2, std::index_sequence_for<As2...>{});
}

int main()
{
auto l1 = (auto && ... args)
{ f1(std::forward<decltype(args)>(args)...); };

auto l2 = (auto && ... args)
{ f2(std::forward<decltype(args)>(args)...); };

f3(l1, l2, std::make_tuple(1, 2l, '3'), std::make_tuple('4', 5ull));
}





share|improve this answer


























  • In this case, how do I pass in the params to f1 and f2?

    – WhatABeautifulWorld
    Jan 2 at 21:37











  • @WhatABeautifulWorld - do you mean: to fix a precise set of types of arguments?

    – max66
    Jan 2 at 21:40











  • what I mean is when I call f3, I offer f1 and f2. I also need to pass in the params for f1 and f2. How do I do that?

    – WhatABeautifulWorld
    Jan 2 at 21:42






  • 1





    @WhatABeautifulWorld - " if I don't have std::apply how do I do that?" - through std::make_index_sequence and std::index_sequence (but C++14 is required; in C++11 you have to write a substitute but isn't really difficult); give me some minutes ans I prepare an example.

    – max66
    Jan 2 at 23:28






  • 1





    @WhatABeautifulWorld - answer improved.

    – max66
    Jan 2 at 23:41
















2














You can't.



Because a template functions are set of functions. And you can pass a functions, explicating the template types,



f3(f1<int, long, long>, f2<char, int>);


and not the full set of functions.



The best I can suggest is to wrap your template functions in structs



struct s1
{
template <typename ... Types>
static void f1 (Types ... args1)
{ }
};

struct s2
{
template <typename ... Types>
static void f2 (Types ... args2)
{ }
};


so you can pass to f3() s1 and s2 objects



s1  a;
s2 b;

f3(a, b);


or simply the types



f3<s1, s2>();


As suggested by Jarod42, you can also wrap f1() and f2() inside a couple of lambdas (only from C++14)



auto l1 = (auto&& ... args) { f1(std::forward<decltype(args)>(args)...); };
auto l2 = (auto&& ... args) { f2(std::forward<decltype(args)>(args)...); };

f3(l1, l2)



what I mean is when I call f3, I offer f1 and f2. I also need to pass in the params for f1 and f2. How do I do that?




But the argument for f1() and f2() are the same?
Or are two different sets?



In the first case, you can pass they as template variadic arguments; something as (following the Jarod42's suggestion)



template <typename L1, typename L2, typename ... Args>
void f3 (L1 l1, L2 l2, Args const & ... as)
{
L1(as...);
L2(as...);
}

auto l1 = (auto&& ... args) { f1(std::forward<decltype(args)>(args)...); };
auto l2 = (auto&& ... args) { f2(std::forward<decltype(args)>(args)...); };

f3(l1, l2, 1, '2', 3L, 4ULL);


If you need two different set of argument, you need to wrap the arguments in std::tuple's or something similar.



template <typename L1, typename L2, typename ... As1, typename ... As2>
void f3 (L1 l1, L2 l2, std::tuple<As1...> const & t1, std::tuple<As2...> const & t2)
{
std::apply(l1, t1);
std::apply(l2, t2);
}

auto l1 = (auto&& ... args) { f1(std::forward<decltype(args)>(args)...); };
auto l2 = (auto&& ... args) { f2(std::forward<decltype(args)>(args)...); };

f3(l1, l2, std::make_tuple(1, 2l, '3'), std::make_tuple('4', 5ull));


But take in count that std::apply() is available only from C++17: before is a little more complicated extract the arguments from the tuples.




how do I do that without c++17?




The following is a full C++14 example that unpack tuples using std::index_sequence_for and std::index_sequence



#include <tuple>
#include <iostream>
#include <type_traits>

template <typename ... Ts>
void f1 (Ts ... as)
{ std::cout << "- f1: " << sizeof...(Ts) << " arguments" << std::endl; }

template <typename ... Ts>
void f2 (Ts ... as)
{ std::cout << "- f2: " << sizeof...(Ts) << " arguments" << std::endl; }

template <typename L, typename ... Ts, std::size_t ... Is>
void f3_helper (L l, std::tuple<Ts...> const & t, std::index_sequence<Is...>)
{ l(std::get<Is>(t)...); }

template <typename L1, typename L2, typename ... As1, typename ... As2>
void f3 (L1 l1, L2 l2, std::tuple<As1...> const & t1,
std::tuple<As2...> const & t2)
{
f3_helper(l1, t1, std::index_sequence_for<As1...>{});
f3_helper(l2, t2, std::index_sequence_for<As2...>{});
}

int main()
{
auto l1 = (auto && ... args)
{ f1(std::forward<decltype(args)>(args)...); };

auto l2 = (auto && ... args)
{ f2(std::forward<decltype(args)>(args)...); };

f3(l1, l2, std::make_tuple(1, 2l, '3'), std::make_tuple('4', 5ull));
}





share|improve this answer


























  • In this case, how do I pass in the params to f1 and f2?

    – WhatABeautifulWorld
    Jan 2 at 21:37











  • @WhatABeautifulWorld - do you mean: to fix a precise set of types of arguments?

    – max66
    Jan 2 at 21:40











  • what I mean is when I call f3, I offer f1 and f2. I also need to pass in the params for f1 and f2. How do I do that?

    – WhatABeautifulWorld
    Jan 2 at 21:42






  • 1





    @WhatABeautifulWorld - " if I don't have std::apply how do I do that?" - through std::make_index_sequence and std::index_sequence (but C++14 is required; in C++11 you have to write a substitute but isn't really difficult); give me some minutes ans I prepare an example.

    – max66
    Jan 2 at 23:28






  • 1





    @WhatABeautifulWorld - answer improved.

    – max66
    Jan 2 at 23:41














2












2








2







You can't.



Because a template functions are set of functions. And you can pass a functions, explicating the template types,



f3(f1<int, long, long>, f2<char, int>);


and not the full set of functions.



The best I can suggest is to wrap your template functions in structs



struct s1
{
template <typename ... Types>
static void f1 (Types ... args1)
{ }
};

struct s2
{
template <typename ... Types>
static void f2 (Types ... args2)
{ }
};


so you can pass to f3() s1 and s2 objects



s1  a;
s2 b;

f3(a, b);


or simply the types



f3<s1, s2>();


As suggested by Jarod42, you can also wrap f1() and f2() inside a couple of lambdas (only from C++14)



auto l1 = (auto&& ... args) { f1(std::forward<decltype(args)>(args)...); };
auto l2 = (auto&& ... args) { f2(std::forward<decltype(args)>(args)...); };

f3(l1, l2)



what I mean is when I call f3, I offer f1 and f2. I also need to pass in the params for f1 and f2. How do I do that?




But the argument for f1() and f2() are the same?
Or are two different sets?



In the first case, you can pass they as template variadic arguments; something as (following the Jarod42's suggestion)



template <typename L1, typename L2, typename ... Args>
void f3 (L1 l1, L2 l2, Args const & ... as)
{
L1(as...);
L2(as...);
}

auto l1 = (auto&& ... args) { f1(std::forward<decltype(args)>(args)...); };
auto l2 = (auto&& ... args) { f2(std::forward<decltype(args)>(args)...); };

f3(l1, l2, 1, '2', 3L, 4ULL);


If you need two different set of argument, you need to wrap the arguments in std::tuple's or something similar.



template <typename L1, typename L2, typename ... As1, typename ... As2>
void f3 (L1 l1, L2 l2, std::tuple<As1...> const & t1, std::tuple<As2...> const & t2)
{
std::apply(l1, t1);
std::apply(l2, t2);
}

auto l1 = (auto&& ... args) { f1(std::forward<decltype(args)>(args)...); };
auto l2 = (auto&& ... args) { f2(std::forward<decltype(args)>(args)...); };

f3(l1, l2, std::make_tuple(1, 2l, '3'), std::make_tuple('4', 5ull));


But take in count that std::apply() is available only from C++17: before is a little more complicated extract the arguments from the tuples.




how do I do that without c++17?




The following is a full C++14 example that unpack tuples using std::index_sequence_for and std::index_sequence



#include <tuple>
#include <iostream>
#include <type_traits>

template <typename ... Ts>
void f1 (Ts ... as)
{ std::cout << "- f1: " << sizeof...(Ts) << " arguments" << std::endl; }

template <typename ... Ts>
void f2 (Ts ... as)
{ std::cout << "- f2: " << sizeof...(Ts) << " arguments" << std::endl; }

template <typename L, typename ... Ts, std::size_t ... Is>
void f3_helper (L l, std::tuple<Ts...> const & t, std::index_sequence<Is...>)
{ l(std::get<Is>(t)...); }

template <typename L1, typename L2, typename ... As1, typename ... As2>
void f3 (L1 l1, L2 l2, std::tuple<As1...> const & t1,
std::tuple<As2...> const & t2)
{
f3_helper(l1, t1, std::index_sequence_for<As1...>{});
f3_helper(l2, t2, std::index_sequence_for<As2...>{});
}

int main()
{
auto l1 = (auto && ... args)
{ f1(std::forward<decltype(args)>(args)...); };

auto l2 = (auto && ... args)
{ f2(std::forward<decltype(args)>(args)...); };

f3(l1, l2, std::make_tuple(1, 2l, '3'), std::make_tuple('4', 5ull));
}





share|improve this answer















You can't.



Because a template functions are set of functions. And you can pass a functions, explicating the template types,



f3(f1<int, long, long>, f2<char, int>);


and not the full set of functions.



The best I can suggest is to wrap your template functions in structs



struct s1
{
template <typename ... Types>
static void f1 (Types ... args1)
{ }
};

struct s2
{
template <typename ... Types>
static void f2 (Types ... args2)
{ }
};


so you can pass to f3() s1 and s2 objects



s1  a;
s2 b;

f3(a, b);


or simply the types



f3<s1, s2>();


As suggested by Jarod42, you can also wrap f1() and f2() inside a couple of lambdas (only from C++14)



auto l1 = (auto&& ... args) { f1(std::forward<decltype(args)>(args)...); };
auto l2 = (auto&& ... args) { f2(std::forward<decltype(args)>(args)...); };

f3(l1, l2)



what I mean is when I call f3, I offer f1 and f2. I also need to pass in the params for f1 and f2. How do I do that?




But the argument for f1() and f2() are the same?
Or are two different sets?



In the first case, you can pass they as template variadic arguments; something as (following the Jarod42's suggestion)



template <typename L1, typename L2, typename ... Args>
void f3 (L1 l1, L2 l2, Args const & ... as)
{
L1(as...);
L2(as...);
}

auto l1 = (auto&& ... args) { f1(std::forward<decltype(args)>(args)...); };
auto l2 = (auto&& ... args) { f2(std::forward<decltype(args)>(args)...); };

f3(l1, l2, 1, '2', 3L, 4ULL);


If you need two different set of argument, you need to wrap the arguments in std::tuple's or something similar.



template <typename L1, typename L2, typename ... As1, typename ... As2>
void f3 (L1 l1, L2 l2, std::tuple<As1...> const & t1, std::tuple<As2...> const & t2)
{
std::apply(l1, t1);
std::apply(l2, t2);
}

auto l1 = (auto&& ... args) { f1(std::forward<decltype(args)>(args)...); };
auto l2 = (auto&& ... args) { f2(std::forward<decltype(args)>(args)...); };

f3(l1, l2, std::make_tuple(1, 2l, '3'), std::make_tuple('4', 5ull));


But take in count that std::apply() is available only from C++17: before is a little more complicated extract the arguments from the tuples.




how do I do that without c++17?




The following is a full C++14 example that unpack tuples using std::index_sequence_for and std::index_sequence



#include <tuple>
#include <iostream>
#include <type_traits>

template <typename ... Ts>
void f1 (Ts ... as)
{ std::cout << "- f1: " << sizeof...(Ts) << " arguments" << std::endl; }

template <typename ... Ts>
void f2 (Ts ... as)
{ std::cout << "- f2: " << sizeof...(Ts) << " arguments" << std::endl; }

template <typename L, typename ... Ts, std::size_t ... Is>
void f3_helper (L l, std::tuple<Ts...> const & t, std::index_sequence<Is...>)
{ l(std::get<Is>(t)...); }

template <typename L1, typename L2, typename ... As1, typename ... As2>
void f3 (L1 l1, L2 l2, std::tuple<As1...> const & t1,
std::tuple<As2...> const & t2)
{
f3_helper(l1, t1, std::index_sequence_for<As1...>{});
f3_helper(l2, t2, std::index_sequence_for<As2...>{});
}

int main()
{
auto l1 = (auto && ... args)
{ f1(std::forward<decltype(args)>(args)...); };

auto l2 = (auto && ... args)
{ f2(std::forward<decltype(args)>(args)...); };

f3(l1, l2, std::make_tuple(1, 2l, '3'), std::make_tuple('4', 5ull));
}






share|improve this answer














share|improve this answer



share|improve this answer








edited Jan 2 at 23:48

























answered Jan 2 at 21:35









max66max66

38.7k74473




38.7k74473













  • In this case, how do I pass in the params to f1 and f2?

    – WhatABeautifulWorld
    Jan 2 at 21:37











  • @WhatABeautifulWorld - do you mean: to fix a precise set of types of arguments?

    – max66
    Jan 2 at 21:40











  • what I mean is when I call f3, I offer f1 and f2. I also need to pass in the params for f1 and f2. How do I do that?

    – WhatABeautifulWorld
    Jan 2 at 21:42






  • 1





    @WhatABeautifulWorld - " if I don't have std::apply how do I do that?" - through std::make_index_sequence and std::index_sequence (but C++14 is required; in C++11 you have to write a substitute but isn't really difficult); give me some minutes ans I prepare an example.

    – max66
    Jan 2 at 23:28






  • 1





    @WhatABeautifulWorld - answer improved.

    – max66
    Jan 2 at 23:41



















  • In this case, how do I pass in the params to f1 and f2?

    – WhatABeautifulWorld
    Jan 2 at 21:37











  • @WhatABeautifulWorld - do you mean: to fix a precise set of types of arguments?

    – max66
    Jan 2 at 21:40











  • what I mean is when I call f3, I offer f1 and f2. I also need to pass in the params for f1 and f2. How do I do that?

    – WhatABeautifulWorld
    Jan 2 at 21:42






  • 1





    @WhatABeautifulWorld - " if I don't have std::apply how do I do that?" - through std::make_index_sequence and std::index_sequence (but C++14 is required; in C++11 you have to write a substitute but isn't really difficult); give me some minutes ans I prepare an example.

    – max66
    Jan 2 at 23:28






  • 1





    @WhatABeautifulWorld - answer improved.

    – max66
    Jan 2 at 23:41

















In this case, how do I pass in the params to f1 and f2?

– WhatABeautifulWorld
Jan 2 at 21:37





In this case, how do I pass in the params to f1 and f2?

– WhatABeautifulWorld
Jan 2 at 21:37













@WhatABeautifulWorld - do you mean: to fix a precise set of types of arguments?

– max66
Jan 2 at 21:40





@WhatABeautifulWorld - do you mean: to fix a precise set of types of arguments?

– max66
Jan 2 at 21:40













what I mean is when I call f3, I offer f1 and f2. I also need to pass in the params for f1 and f2. How do I do that?

– WhatABeautifulWorld
Jan 2 at 21:42





what I mean is when I call f3, I offer f1 and f2. I also need to pass in the params for f1 and f2. How do I do that?

– WhatABeautifulWorld
Jan 2 at 21:42




1




1





@WhatABeautifulWorld - " if I don't have std::apply how do I do that?" - through std::make_index_sequence and std::index_sequence (but C++14 is required; in C++11 you have to write a substitute but isn't really difficult); give me some minutes ans I prepare an example.

– max66
Jan 2 at 23:28





@WhatABeautifulWorld - " if I don't have std::apply how do I do that?" - through std::make_index_sequence and std::index_sequence (but C++14 is required; in C++11 you have to write a substitute but isn't really difficult); give me some minutes ans I prepare an example.

– max66
Jan 2 at 23:28




1




1





@WhatABeautifulWorld - answer improved.

– max66
Jan 2 at 23:41





@WhatABeautifulWorld - answer improved.

– max66
Jan 2 at 23:41





Popular posts from this blog

MongoDB - Not Authorized To Execute Command

Npm cannot find a required file even through it is in the searched directory

in spring boot 2.1 many test slices are not allowed anymore due to multiple @BootstrapWith