Как передать функцию шаблона в список аргументов шаблона

Предположим, у меня есть template функция:

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

Как я могу передать все это template другому template?

Если produce_5_function был функтором, не было бы проблем:

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 >()();

но я хочу быть в состоянии сделать это с помощью необработанного шаблона функции:

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

Я подозреваю, что ответ «вы не можете сделать это».

23

Решение

Я подозреваю, что ответ «вы не можете сделать это».

Да, это так, вы не можете передать шаблон функции в качестве аргумента шаблона. Из 14.3.3:

Аргумент шаблона для параметра шаблона шаблона должен быть
имя шаблона класса или шаблона псевдонима, выраженное как
ID-выражение.

Функция шаблона должна быть создана до Вы передаете его другому шаблону. Одним из возможных решений является передача типа класса, который содержит статический produce_5_function вот так:

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>()();

Используя шаблоны псевдонимов, я мог бы стать немного ближе:

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);
15

Другие решения

Как насчет упаковки этой функции?

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

Тогда вы можете использовать оболочку вместо функции:

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

Использование одной только функции шаблона не будет работать, нет такой вещи как «функции шаблона шаблона».

2

По вопросам рекламы [email protected]