如何在模板参数列表中传递模板函数

时间:2022-10-16 21:25:34

Suppose I have a template function:

假设我有一个模板功能:

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

How can I pass this entire template to another template?

如何将整个模板传递给另一个模板?

If produce_5_function was a functor, there would be no problem:

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

but I want to be able to do this with a raw function template:

但我希望能够使用原始函数模板执行此操作:

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

I suspect the answer is "you cannot do this".

我怀疑答案是“你不能这样做”。

2 个解决方案

#1


14  

I suspect the answer is "you cannot do this".

我怀疑答案是“你不能这样做”。

Yes, that is the case, you cannot pass a function template as a template argument. From 14.3.3:

是的,就是这种情况,您不能将函数模板作为模板参数传递。从14.3.3开始:

A template-argument for a template template-parameter shall be the name of a class template or an alias template, expressed as id-expression.

模板template-parameter的template-argument应该是类模板或别名模板的名称,表示为id-expression。

The template function needs to be instantiated before you pass it to the other template. One possible solution is to pass a class type that holds a static produce_5_function like so:

在将模板函数传递给其他模板之前,需要对其进行实例化。一种可能的解决方案是传递一个包含静态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>()();

Using alias templates, I could get a little closer:

使用别名模板,我可以更接近:

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


2  

How about wrapping that function?

包装那个功能怎么样?

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

Then you can use the wrapper instead of the function:

然后你可以使用包装器而不是函数:

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

Using the template function alone will not work, there's no such thing as "template template functions".

单独使用模板功能是行不通的,没有“模板模板功能”这样的功能。

#1


14  

I suspect the answer is "you cannot do this".

我怀疑答案是“你不能这样做”。

Yes, that is the case, you cannot pass a function template as a template argument. From 14.3.3:

是的,就是这种情况,您不能将函数模板作为模板参数传递。从14.3.3开始:

A template-argument for a template template-parameter shall be the name of a class template or an alias template, expressed as id-expression.

模板template-parameter的template-argument应该是类模板或别名模板的名称,表示为id-expression。

The template function needs to be instantiated before you pass it to the other template. One possible solution is to pass a class type that holds a static produce_5_function like so:

在将模板函数传递给其他模板之前,需要对其进行实例化。一种可能的解决方案是传递一个包含静态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>()();

Using alias templates, I could get a little closer:

使用别名模板,我可以更接近:

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


2  

How about wrapping that function?

包装那个功能怎么样?

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

Then you can use the wrapper instead of the function:

然后你可以使用包装器而不是函数:

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

Using the template function alone will not work, there's no such thing as "template template functions".

单独使用模板功能是行不通的,没有“模板模板功能”这样的功能。