C ++ 11: puedo pasar de múltiples args a tuple, pero ¿puedo pasar de tuple a multiple args?

Posible duplicado:
¿Cómo puedo expandir una tupla en los argumentos de la función de plantilla variadic?
“Desempaquetar” una tupla para llamar a un puntero de función coincidente

En las plantillas de C ++ 11, ¿hay alguna manera de usar una tupla como argumento individual de una función (posiblemente una plantilla)?

Ejemplo:
Digamos que tengo esta función:

void foo(int a, int b) { } 

Y tengo la tuple auto bar = std::make_tuple(1, 2) .

¿Puedo usar eso para llamar a foo(1, 2) de forma temporal?

No me refiero simplemente a foo(std::get(bar), std::get(bar)) ya que quiero hacer esto en una plantilla que no conoce el número de argumentos.

Un ejemplo más completo:

 template void caller(Func func, Args... args) { auto argtuple = std::make_tuple(args...); do_stuff_with_tuple(argtuple); func(insert_magic_here(argtuple)); // <-- this is the hard part } 

Debo señalar que preferiría no crear una plantilla que funcione para una arg, otra que funcione para dos, etc.

Pruebe algo como esto:

 // implementation details, users never invoke these directly namespace detail { template  struct call_impl { static void call(F f, Tuple && t) { call_impl::call(f, std::forward(t)); } }; template  struct call_impl { static void call(F f, Tuple && t) { f(std::get(std::forward(t))...); } }; } // user invokes this template  void call(F f, Tuple && t) { typedef typename std::decay::type ttype; detail::call_impl::value, std::tuple_size::value>::call(f, std::forward(t)); } 

Ejemplo:

 #include  int main() { auto t = std::make_tuple("%d, %d, %d\n", 1,2,3); call(std::printf, t); } 

Con algo de magia extra y usando std::result_of , probablemente también puedas hacer que la cosa entera devuelva el valor de retorno correcto.

Cree una “tupla de índice” (una tupla de enteros en tiempo de comstackción) y luego reenvíela a otra función que deduzca los índices como un paquete de parámetros y los use en una expansión de paquete para llamar a std::get en la tupla:

 #include  template void caller_impl(Func func, Tuple&& t, redi::index_tuple) { func(std::get(t)...); } template void caller(Func func, Args... args) { auto argtuple = std::make_tuple(args...); do_stuff_with_tuple(argtuple); typedef redi::to_index_tuple indices; caller_impl(func, argtuple, indices()); } 

Mi implementación de index_tuple está en https://gitlab.com/redistd/redistd/blob/master/include/redi/index_tuple.h pero depende de los alias de las plantillas, así que si tu comstackdor no admite eso necesitarás modificar usar “template typedefs” tipo C ++ 03 y reemplazar las últimas dos líneas de la caller con

  typedef typename redi::make_index_tuple::type indices; caller_impl(func, argtuple, indices()); 

Una utilidad similar se estandarizó como std::index_sequence en C ++ 14 (vea index_seq.h para una implementación independiente de C ++ 11).