Подтвердить что ты не робот

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

Предположим, что у меня есть функция 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 >()();

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

4b9b3361

Ответ 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 >()();

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