2013-03-27 78 views
18

假设我有一个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>()(); 

我怀疑答案是“你不可以做这个”。

回答

12

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

是的,就是这样,您不能将函数模板作为模板参数传递。从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); 
+0

有一个根本原因模板的模板参数不能是功能模板?这可能会在未来得到解决吗? – Olumide 2018-02-08 16:46:53

+0

@Olumide:可能是因为它有很多额外的复杂性并且很容易解决(请参阅mfontanini的回答)。部分专业化也是如此,这比模板模板参数使用得更多。 – 2018-02-26 17:57:24

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

使用模板功能还不行,有没有这样的事情“模板模板函数”。