我正在尝试在C ++ 11模板上实现μ-recursive function,但我有替换功能的问题。
S<f, g_1, .... g_m>::apl(x_1,... x_n) = f::apl(g_1(x_1,... x_n), ... g_m(x_1,... x_n));
由于任何可能的n(args数),我使用可变参数模板。
我无法在S
的私有函数中进行递归,使用S's
类型模板参数包。
有可能修复它,或采取其他方式吗?可能是通过使用嵌套结构,但函数?
问题代码:
template<typename F, typename g, typename ... G>
struct S{
static void get_g_results(arguments const & input, arguments& output)
{
}
/* error is here :no matching function for call to 'get_g_results'
get_g_results<G...>(v, output);
candidate template ignored: "could't infer template argument 'q'"*/
template<typename q, typename ... Q>
static void get_g_results(arguments const & input, arguments& output) {
output.push_back(q::apply(input));
get_g_results<Q...>(input, output);
}
static nat apply(arguments const & v) {
arguments output(1, g::apply(v));
get_g_results<G...>(v, output);
return F::apply(output);
}
template<typename ... T>
static nat apl(T ... ret) {
return apply(get_arguments(ret...));
}
}
S<N,U<2, 1> >::apl(5, 3);
所有代码:
using namespace std;
typedef unsigned nat;
typedef vector<nat> arguments;
void get_arguments(arguments &a)
{
a.size();
}
template<typename ... T>
void get_arguments(arguments& a,nat first, T ... rest)
{
a.push_back(first);
get_arguments(a, rest...);
}
template<typename ... T>
arguments get_arguments(nat first, T ... rest)
{
arguments a(1, first);
get_arguments(a, rest...);
return a;
}
template <nat n, nat m>
struct U{
static const nat arg_num = n;
static_assert(n != 0 && m != 0 && n >= m, "invalid template parametrs ");
static nat apply(arguments const & v) {
assert(v.size() == arg_num);
return v[m - 1];
}
template<typename ... T>
static nat apl(T ... ret) {
return apply(get_arguments(ret...));
}
};
struct N {
static const nat arg_num = 1;
static nat apply(arguments const & v) {
assert(v.size() == arg_num);
return v[0] + 1;
}
template<typename ... T>
static nat apl(T ... ret) {
return apply(get_arguments(ret...));
}
};
template<typename F, typename g, typename ... G>
struct S{
static const nat arg_num = g::arg_num;
static const nat f_arg_num = F::arg_num;
private:
static void get_g_results(arguments const & input, arguments& output)
{
}
/* error is here :no matching function for call to 'get_g_results'
get_g_results<G...>(v, output);
candidate template ignored: "could't infer template argument 'q'"*/
template<typename q, typename ... Q>
static void get_g_results(arguments const & input, arguments& output) {
output.push_back(q::apply(input));
get_g_results<Q...>(input, output);
}
static nat apply(arguments const & v) {
assert(v.size() == arg_num);
arguments output(1, g::apply(v));
get_g_results<G...>(v, output);
return F::apply(output);
}
public:
template<typename ... T>
static nat apl(T ... ret) {
return apply(get_arguments(ret...));
}
};
int main(int argc, const char * argv[]) {
cout << U<4, 3>::apl(1, 2, 3, 4) << endl;// output: 3
cout << N::apl(4) << endl; // output: 5
cout << S<N,U<2, 1> >::apl(5, 3) << endl;
// error:could't infer template argument 'q'
return 0;
}
答案 0 :(得分:2)
这应该可以解决问题:
template<typename F, typename... G>
struct S {
static nat apply(arguments const & args) {
arguments output = { G::apply(args)... };
return F::apply(output);
}
template<typename... T>
static nat apl(T... x) {
arguments args = { static_cast<nat>(x)... };
return apply(args);
}
};