在其静态递归函数中展开结构类型模板参数包



我正在尝试在 C++11 模板上实现μ递归函数,但我对替换函数有问题。 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;
}

这应该可以解决问题:

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

在此处观看现场演示!

最新更新