【问题标题】:Expand struct type template parameter pack in its static recursive function在其静态递归函数中展开结构类型模板参数包
【发布时间】:2013-11-29 21:38:09
【问题描述】:

我正在尝试在 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 number),我使用可变参数模板。 我无法在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;
}

【问题讨论】:

  • NN::apl(4)S&lt;N,U&lt;2,2&gt;&gt; 中是什么? (我没有看到任何声明..)
  • 嗯,错误源自这里:get_g_results&lt;G...&gt;(v, output); 当您没有为G 提供任何模板参数时,您没有为get_g_results 指定任何模板参数,而q 需要一个(不能从函数参数中推导出来)。
  • 抱歉,我忘记了 N. Fixed。但是我该如何解决呢?

标签: c++ templates c++11


【解决方案1】:

这应该可以解决问题:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-08-04
    • 1970-01-01
    • 1970-01-01
    • 2019-03-23
    • 1970-01-01
    • 2018-03-31
    • 2023-01-10
    • 1970-01-01
    相关资源
    最近更新 更多