|
|
||||||
|
#1
|
|
|
|
|
Hello,
I'd like to know what is the way to unpack a tuple into function call arguments. I've seen in an old article for the standard that a function called std::apply( Func, tuple ) did that, but it is nowhere to be found in the gcc 4.3.2 C++0x implementation that I currently experiment with. void func( int a, int b, int c) { } std::tuple <int, int, int> myargs(1, 2, 3); would call something like this unwrapping the tuple into each of the individual function arguments. I could write this wrapper myself, but maybe it already exists in some form. func( get<0>(myargs), get<1>(myargs), get<2>(myargs) ); I'm looking for the generic solution using variadic templates and tuple manipulation if someone knows. Thanks |
|
|
|
#2
|
|
|
|
|
metarox <legault.david> writes:
[..] > std::tuple <int, int, int> myargs(1, 2, 3); > > would call something like this unwrapping the tuple into each of the > individual function arguments. I could write this wrapper myself, but > maybe it already exists in some form. > > func( get<0>(myargs), get<1>(myargs), get<2>(myargs) ); > > I'm looking for the generic solution using variadic templates and > tuple manipulation if someone knows. I am not aware of an easy technique other than to write your own apply function, which isn't easy --- you have to recursively unpack the tuple until you have unpacked all the elements into separate arguments, which you can pass to your target function. Anthony |
|
#3
|
|
|
|
|
On Mar 12, 11:46 am, metarox <legaultda> wrote:
> Hello, > > I'd like to know what is the way to unpack a tuple into function call > arguments. Try the following: template<bool enable, class T> struct enable_if {}; template<class T> struct enable_if<true, T> { typedef T type; }; template<size_t argIndex, size_t argSize, class... Args, class... Unpacked, class F> inline typename enable_if<(argIndex == argSize), void>::type apply_args_impl(const std::tuple<Args...>&& t, F f, Unpacked&&... u) { f(u...); // I think this should be f(std::forward<Unpacked> (u)...); } template<size_t argIndex, size_t argSize, class... Args, class... Unpacked, class F> inline typename enable_if<(argIndex < argSize), void>::type apply_args_impl(const std::tuple<Args...>&& t, F f, Unpacked&&... u) { apply_args_impl<argIndex + 1, argSize>(t, f, u..., std::get<argIndex>(t)); } template<class... Args, class F> inline void apply_args(const std::tuple<Args...>&& t, F f) { apply_args_impl<0, sizeof...(Args)>(t, f); } There are other possibilities, such as creating a list of indices. Yechezkel Mett |
|
#4
|
|
|
|
|
Anthony Williams wrote:
> metarox <legault.david> writes: >> I'd like to know what is the way to unpack a tuple into function call >> arguments. I've seen in an old article for the standard that a >> function called std::apply( Func, tuple ) did that, but it is nowhere >> to be found in the gcc 4.3.2 C++0x implementation that I currently >> experiment with. >> >> I'm looking for the generic solution using variadic templates and >> tuple manipulation if someone knows. > > I am not aware of an easy technique other than to write your own apply > function, which isn't easy --- you have to recursively unpack the tuple > until you have unpacked all the elements into separate arguments, which > you can pass to your target function. Here's one I managed to write using variadic templates in C++0x. This compiles and works in gcc 4.3.2. It doesn't even require that function's parameter types and tuple's types are exactly the same: #include <tuple> // Recursive case, unpack Nth argument template<unsigned int N> struct Apply_aux { template<typename... ArgsF, typename... ArgsT, typename... Args> static void apply(void (*f)(ArgsF...), std::tuple<ArgsT...> const& t, Args... args) { Apply_aux<N-1>::apply(f, t, std::get<N-1>(t), args...); } }; // Terminal case, call the function with unpacked arguments template<> struct Apply_aux<0> { template<typename... ArgsF, typename... ArgsT, typename... Args> static void apply(void (*f)(ArgsF...), std::tuple<ArgsT...> const&, Args... args) { f(args...); } }; // Actual apply function template<typename... ArgsF, typename... ArgsT> void apply(void (*f)(ArgsF...), std::tuple<ArgsT...> const& t) { Apply_aux<sizeof...(ArgsT)>::apply(f, t); } // Testing #include <string> #include <iostream> void f(int p1, double p2, std::string p3) { std::cout << "int=" << p1 << ", double=" << p2 << ", string=" << p3 << std::endl; } void g(int p1, std::string p2) { std::cout << "int=" << p1 << ", string=" << p2 << std::endl; } int main() { std::tuple<int, double, char const*> tup(1, 2.0, "xxx"); apply(&f, tup); apply(&g, std::make_tuple(4, "yyy")); } > g++ -std=c++0x tupleunpack.cc > ./a.out int=1, double=2, string=xxx int=4, string=yyy |
|
#5
|
|
|
|
|
On Mar 12, 11:46 am, metarox <legaultda> wrote:
[..] > std::tuple <int, int, int> myargs(1, 2, 3); > > would call something like this unwrapping the tuple into each of the > individual function arguments. I could write this wrapper myself, but > maybe it already exists in some form. > > func( get<0>(myargs), get<1>(myargs), get<2>(myargs) ); > > I'm looking for the generic solution using variadic templates and > tuple manipulation if someone knows. Here is the code posted previously in this group. One has to marvel at unsurpassed clarity :-) #include <cstddef> #include <tuple> #include <utility> template<std::size_t...> struct index_tuple{}; template<std::size_t I, typename IndexTuple, typename... Types> struct make_indices_impl; template<std::size_t I, std::size_t... Indices, typename T, typename... Types> struct make_indices_impl<I, index_tuple<Indices...>, T, Types...> { typedef typename make_indices_impl<I + 1, index_tuple<Indices..., I>, Types...>::type type; }; template<std::size_t I, std::size_t... Indices> struct make_indices_impl<I, index_tuple<Indices...> > { typedef index_tuple<Indices...> type; }; template<typename... Types> struct make_indices : make_indices_impl<0, index_tuple<>, Types...> {}; template <class... Args> void some_func(Args&&...){} template <class... Args> class store { public: store(Args... args) : members(args...) {} void forward() { typedef typename make_indices<Args...>::type Indices; return forward0(Indices(), members); } private: template <std::size_t... Indices> static void forward0(index_tuple<Indices...>, std::tuple<Args...>&&args) { some_func(std::forward<Args>(std::get<Indices>(arg s))...); } std::tuple<Args...> members; }; int main() { store<int, bool, double>(42, true, 1.2).forward(); } |
|
#6
|
|
|
|
|
Thanks to all of you
Hopefully they add it in the <utility> header or somewhere so we don't have to ask too often! |
|
|
| Similar Threads | |
| Cython + tuple unpacking Hello, The following code will crash with a segfault when compiled using cython (v0.11) def func(): for (a, b) ,c ,d in zip(zip(range(3), range(3)), range(3),... |
|
| Passing a tuple to a function as multiple arguments Hello, Let's say I have a function with a variable number of arguments(please ignore syntax errors): def myfunc(a,b,c,d,...): and I have a tuple whose contents I want to... |
|
| Unpacking sequences and keywords in one function call Stupid question #983098403: I can't seem to pass an unpacked sequence and keyword arguments to a function at the same time. What am I doing wrong? def f(*args, **kw): for a... |
|
| problems when unpacking tuple ... Dear all, Maybe I stared on the monitor for too long, because I cannot find the bug ... My script "transition_filter.py" starts with the following lines: import sys for... |
|
| Tuple Unpacking in raise Hello All, Is this a bug? Why is this tuple getting unpacked by raise? Am I missing some subtle logic? Why does print not work the same way as raise? Both are statements.... |
|
|
All times are GMT. The time now is 01:48 PM. | Privacy Policy
|