Multiple variadic templates function [closed]
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
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.
add a comment |
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
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 namesf1
andf2
in two ways - do you wantf3
to call the function passed to it, or the function actually namedf1
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
add a comment |
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
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
c++ c++11 templates variadic-templates variadic-functions
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 namesf1
andf2
in two ways - do you wantf3
to call the function passed to it, or the function actually namedf1
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
add a comment |
Could you explain your expected behavior? And it's confusing that you use the namesf1
andf2
in two ways - do you wantf3
to call the function passed to it, or the function actually namedf1
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
add a comment |
1 Answer
1
active
oldest
votes
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));
}
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?" - throughstd::make_index_sequence
andstd::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
|
show 13 more comments
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
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));
}
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?" - throughstd::make_index_sequence
andstd::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
|
show 13 more comments
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));
}
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?" - throughstd::make_index_sequence
andstd::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
|
show 13 more comments
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));
}
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));
}
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?" - throughstd::make_index_sequence
andstd::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
|
show 13 more comments
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?" - throughstd::make_index_sequence
andstd::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
|
show 13 more comments
Could you explain your expected behavior? And it's confusing that you use the names
f1
andf2
in two ways - do you wantf3
to call the function passed to it, or the function actually namedf1
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