Consider the case of a templated function with variadic template arguments:
template<typename Tret, typename... T> Tret func(const T&... t);
Now, I have a tuple t
of values. How do I call func()
using the tuple values as arguments?
I've read about the bind()
function object, with call()
function, and also the apply()
function in different some now-obsolete documents. The GNU GCC 4.4 implementation seems to have a call()
function in the bind()
class, but there is very little documentation on the subject.
Some people suggest hand-written recursive hacks, but the true value of variadic template arguments is to be able to use them in cases like above.
Does anyone have a solution to is, or hint on where to read about it?
This simple solution works for me:
How about this:
The
run_tuple
function template takes the given tuple and pass its elements individually to the given function. It carries out its work by recursively calling its helper function templatesexplode_tuple
. It's important thatrun_tuple
passes the tuple's size toexplode_tuple
; that number acts as a counter for how many elements to extract.If the tuple is empty, then
run_tuple
calls the first version ofexplode_tuple
with the remote function as the only other argument. The remote function is called with no arguments and we're done. If the tuple is not empty, a higher number is passed to the second version ofexplode_tuple
, along with the remote function. A recursive call toexplode_tuple
is made, with the same arguments, except the counter number is decreased by one and (a reference to) the last tuple element is tacked on as an argument after the remote function. In a recursive call, either the counter isn't zero, and another call is made with the counter decreased again and the next-unreferenced element is inserted in the argument list after the remote function but before the other inserted arguments, or the counter reaches zero and the remote function is called with all the arguments accumulated after it.I'm not sure I have the syntax of forcing a particular version of a function template right. I think you can use a pointer-to-function as a function object; the compiler will automatically fix it.
All this implementations are good. But due to use of pointer to member function compiler often cannot inline the target function call (at least gcc 4.8 can't, no matter what Why gcc can't inline function pointers that can be determined?)
But things changes if send pointer to member function as template arguments, not as function params:
And ussage:
Proof of inlinable http://goo.gl/5UqVnC
With small changes, we can "overload"
apply_tuple
:Plus this is the only one solution which works with templated functions.
I am evaluating MSVS 2013RC, and it failed to compile some of the previous solutions proposed here in some cases. For example, MSVS will fail to compile "auto" returns if there are too many function parameters, because of a namespace imbrication limit (I sent that info to Microsoft to have it corrected). In other cases, we need access to the function's return, although that can also be done with a lamda: the following two examples give the same result..
And thanks again to those who posted answers here before me, I wouldn't have gotten to this without it... so here it is:
Why not just wrap your variadic arguments into a tuple class and then use compile time recursion (see link) to retrieve the index you are interested in. I find that unpacking variadic templates into a container or collection may not be type safe w.r.t. heterogeneous types
Here's my code if anyone is interested
Basically at compile time the compiler will recursively unroll all arguments in various inclusive function calls <N> -> calls <N-1> -> calls ... -> calls <0> which is the last one and the compiler will optimize away the various intermediate function calls to only keep the last one which is the equivalent of func(arg1, arg2, arg3, ...)
Provided are 2 versions, one for a function called on an object and the other for a static function.