Cómo pasar una función de plantilla en una lista de argumentos de plantilla

Supongamos que tengo una función de template :

 template T produce_5_function() { return T(5); } 

¿Cómo puedo pasar esta template completa a otra template ?

Si produce_5_function fue un funtor, no habría problema:

 template struct produce_5_functor { T operator()() const { return T(5); } }; template<templateclass F> struct client_template { int operator()() const { return F()(); } }; int five = client_template()(); 

pero quiero poder hacer esto con una plantilla de función sin formato:

 template struct client_template { int operator()() const { return F(); } }; int five = client_template()(); 

Sospecho que la respuesta es “no puedes hacer esto”.

Sospecho que la respuesta es “no puedes hacer esto”.

Sí, ese es el caso, no puede pasar una plantilla de función como argumento de plantilla. De 14.3.3:

Una plantilla-argumento para una plantilla plantilla-parámetro será el nombre de una plantilla de clase o una plantilla de alias, expresada como expresión-id.

La función de plantilla necesita ser instanciada antes de pasarla a la otra plantilla. Una solución posible es pasar un tipo de clase que contiene una función estática de produce_5_function así:

 template struct Workaround { static T produce_5_functor() { return T(5); } }; templateclass F> struct client_template { int operator()() const { return F::produce_5_functor(); } }; int five = client_template()(); 

Usando plantillas de alias, podría acercarme un poco más:

 template  T produce_5_functor() { return T(5); } template  using prod_func = R(); templateclass F> struct client_template { int operator()(F f) const { return f(); } }; int five = client_template()(produce_5_functor); 

¿Qué hay de envolver esa función?

 template struct produce_5_function_wrapper { T operator()() const { return produce_5_function(); } }; 

Entonces puede usar el contenedor en lugar de la función:

 int five = client_template< produce_5_function_wrapper >()(); 

El uso de la función de plantilla por sí solo no funcionará, no existe la “plantilla de funciones de plantilla”.