在其静态递归函数中展开struct type template parameter pack

时间:2013-11-16 13:21:49

标签: c++ templates c++11

我正在尝试在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;
}

1 个答案:

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

查看live demo here