template safe plantillas linebreaksbr length ifequal c++ templates c++11 function-templates

c++ - safe - linebreaksbr django



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

Supongamos que tengo una función de template :

template<typename T> T produce_5_function() { return T(5); }

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

Si produce_5_function era un functor, no habría ningún problema:

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

pero quiero poder hacer esto con una plantilla de función en bruto:

template<??? F> struct client_template { int operator()() const { return F<int>(); } }; int five = client_template< produce_5_function >()();

Sospecho que la respuesta es "no se puede hacer esto".


Sospecho que la respuesta es "no se puede hacer esto".

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

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

La función de plantilla debe ser instanciada antes de pasarla a la otra plantilla. Una posible solución es pasar un tipo de clase que contenga una produce_5_function estática como esta:

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

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

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


¿Qué hay de envolver esa función?

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

Luego puedes usar la envoltura en lugar de la función:

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

Usar la función de plantilla solo no funcionará, no existe tal cosa como "funciones de plantilla de plantilla".