Как передать функцию шаблона в списке аргументов шаблона
Предположим, что у меня есть функция 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 >()();
Я подозреваю, что ответ "вы не можете этого сделать".
Ответы
Ответ 1
Я подозреваю, что ответ "вы не можете этого сделать".
Да, это так, вы не можете передать шаблон функции в качестве аргумента шаблона. Из 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);
Ответ 2
Как обернуть эту функцию?
template<typename T>
struct produce_5_function_wrapper {
T operator()() const { return produce_5_function<T>(); }
};
Затем вы можете использовать оболочку вместо функции:
int five = client_template< produce_5_function_wrapper >()();
Использование только функции шаблона не будет работать, нет такой вещи, как "шаблонные шаблоны".