Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/url/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 基于模板参数的另一个包创建参数包_C++_Templates_C++11_Metaprogramming_Variadic Templates - Fatal编程技术网

C++ 基于模板参数的另一个包创建参数包

C++ 基于模板参数的另一个包创建参数包,c++,templates,c++11,metaprogramming,variadic-templates,C++,Templates,C++11,Metaprogramming,Variadic Templates,假设有几个模板类(结构),它们的对象构成了序列-让我们称它们为N_mod(N-特定类的说明符),以及定义序列中第一个元素的特殊类-first_mod。除第一个模块外,每个类都有自己的“接口生成器”-N\u生成器---模板类: template<int targ> struct First_mod //First element in sequence - without appropriate builder interface { }; //Let's consider tw

假设有几个模板类(结构),它们的对象构成了序列-让我们称它们为N_mod(N-特定类的说明符),以及定义序列中第一个元素的特殊类-first_mod。除第一个模块外,每个类都有自己的“接口生成器”-N\u生成器---模板类:

template<int targ>
struct First_mod //First element in sequence - without appropriate builder interface
{   };

//Let's consider two types of N_mod - A_mod and B_mod
template<int targ, int param>
struct A_mod
{   };

template<int param>
struct A_builder//Builder for A_mod objects
{   };

template<int targ, int param>
struct B_mod
{   };

template<int param>
struct B_builder//Builder for B_mod objects
{   };
模板
struct First_mod//序列中的第一个元素-没有适当的生成器界面
{   };
/让我们考虑两种类型的NU-MOD-AYMOD和BMODD。
样板
结构A_mod
{   };
样板
struct A_builder//A_mod objects的builder
{   };
样板
结构B_mod
{   };
样板
结构B_生成器//B_mod对象的生成器
{   };
现在,我需要根据以下简单规则,从适当的N\u构建器的现有序列中生成First\u modN\u mod对象序列:

如果N_Mod(i)等于A_Mod则targ(i)=参数(i)-targ(i-1)

else(即N_Mod(i)等于B_Mod)target(i)=参数(i)*target(i-1)

为了清晰起见,我的草图:

template<typename...builders>
struct mod_seq_gen
{
    typedef /*generated First_mod, A_mod and B_mod sequence pack. How to do it?*/ modseq;
};

template<typename...builders>
struct Container
{
    std::tuple</*here must be mod-sequence generator that creates
                mod parameters pack and unpacks them:*/
                mod_seq_gen<builders...>::modseq
              > mod_sequence;
};

int main()
{   
    /*In this case must be generated next sequence and stored in 
     * mod_sequence tuple:
     * First_mod<3> - A_mod<5-3, 5> - B_mod<2*(5-3), 2>
     */
    Container<First_mod<3>, A_builder<5>, B_builder<2>> obj;
}
模板
结构模块顺序生成
{
typedef/*生成第一个\模、A \模和B \模序列包。如何执行?*/modseq;
};
样板
结构容器
{
std::tuple mod_序列;
};
int main()
{   
/*在这种情况下,必须生成下一个序列并存储在
*mod_序列元组:
*第一个模式-A模式-B模式
*/
集装箱obj;
}
我请求帮助您实施mod_seq_gen,或者为整个任务提供一些其他提示

首先,我将转储(编译)解决方案:

#include <tuple>
#include <utility>
#include <iostream>

template<int targ>
struct First_mod //First element in sequence - without appropriate builder interface
{  void print() { std::cout << "First_mod["<<targ<<"]" << std::endl; }  };

//Let's consider two types of N_mod - A_mod and B_mod
template<int targ, int param>
struct A_mod
{  void print() { std::cout << "A_mod["<<targ<<", "<<param<<"]" << std::endl; }  };

template<int param>
struct A_builder//Builder for A_mod objects
{
    // publish the template parameter (not necessary)
    static const int param_value = param;

    // provide a way to compute the current targ
    static constexpr int calc_targ(int prev_targ)
    {
        return param - prev_targ;
    }

    // provide a way to build the type
    template < int targ >
    using type = A_mod<targ, param>;
};

template<int targ, int param>
struct B_mod
{  void print() { std::cout << "B_mod["<<targ<<", "<<param<<"]" << std::endl; }  };

template<int param>
struct B_builder//Builder for B_mod objects
{
    static const int param_value = param;
    static constexpr int calc_targ(int prev_targ)
    {
        return prev_targ * param;
    }

    template < int targ >
    using type = B_mod<targ, param>;
};


// just a helper, wonder if there's something in the Standard Library o.O
template < typename... Tuples >
using tuple_cat_types = decltype(tuple_cat( std::declval<Tuples>()... ));


// the generator of the tuple
template < typename TFirst_mod, typename... TBuilders >
struct gen;

// restrict the first type to a specialization of `First_mod`
// isn't necessary, strictly speaking. We just need the first targ.
// Could as well require a nested `static const int targ = ..;`
template < int first_targ, typename... TBuilders >
struct gen < First_mod<first_targ>, TBuilders... >
{
    // recursive helper for the types to be built
    // general case for no template arguments in the pack
    template < int prev_targ, typename... TBuilders2 >
    struct helper { using type = std::tuple<>; };

    // specialized case for recursion
    // note: the recursion here occurs as a nested typedef, not inheritance
    //       (simplifies use of calculated targ)
    template < int prev_targ, typename TBuilder, typename... TBuilders2 >
    struct helper<prev_targ, TBuilder, TBuilders2...>
    {
        // build type using builder
        static const int targ = TBuilder::calc_targ(prev_targ);
        using built_type = typename TBuilder::template type<targ>;

        // recurse
        using further_types = typename helper<targ, TBuilders2...>::type;

        // concatenate tuple
        using type = tuple_cat_types<std::tuple<built_type>, further_types>;
    };

    // concatenate tuple with First_mod
    using type = tuple_cat_types<std::tuple<First_mod<first_targ>>,
                     typename helper<first_targ, TBuilders...>::type>;
};


int main()
{
    gen<First_mod<3>, A_builder<5>, B_builder<2>>::type x;
    static_assert(std::tuple_size<decltype(x)>::value == 3, "!");
    std::get<0>(x).print();
    std::get<1>(x).print();
    std::get<2>(x).print();
}
首先,我将转储(编译)解决方案:

#include <tuple>
#include <utility>
#include <iostream>

template<int targ>
struct First_mod //First element in sequence - without appropriate builder interface
{  void print() { std::cout << "First_mod["<<targ<<"]" << std::endl; }  };

//Let's consider two types of N_mod - A_mod and B_mod
template<int targ, int param>
struct A_mod
{  void print() { std::cout << "A_mod["<<targ<<", "<<param<<"]" << std::endl; }  };

template<int param>
struct A_builder//Builder for A_mod objects
{
    // publish the template parameter (not necessary)
    static const int param_value = param;

    // provide a way to compute the current targ
    static constexpr int calc_targ(int prev_targ)
    {
        return param - prev_targ;
    }

    // provide a way to build the type
    template < int targ >
    using type = A_mod<targ, param>;
};

template<int targ, int param>
struct B_mod
{  void print() { std::cout << "B_mod["<<targ<<", "<<param<<"]" << std::endl; }  };

template<int param>
struct B_builder//Builder for B_mod objects
{
    static const int param_value = param;
    static constexpr int calc_targ(int prev_targ)
    {
        return prev_targ * param;
    }

    template < int targ >
    using type = B_mod<targ, param>;
};


// just a helper, wonder if there's something in the Standard Library o.O
template < typename... Tuples >
using tuple_cat_types = decltype(tuple_cat( std::declval<Tuples>()... ));


// the generator of the tuple
template < typename TFirst_mod, typename... TBuilders >
struct gen;

// restrict the first type to a specialization of `First_mod`
// isn't necessary, strictly speaking. We just need the first targ.
// Could as well require a nested `static const int targ = ..;`
template < int first_targ, typename... TBuilders >
struct gen < First_mod<first_targ>, TBuilders... >
{
    // recursive helper for the types to be built
    // general case for no template arguments in the pack
    template < int prev_targ, typename... TBuilders2 >
    struct helper { using type = std::tuple<>; };

    // specialized case for recursion
    // note: the recursion here occurs as a nested typedef, not inheritance
    //       (simplifies use of calculated targ)
    template < int prev_targ, typename TBuilder, typename... TBuilders2 >
    struct helper<prev_targ, TBuilder, TBuilders2...>
    {
        // build type using builder
        static const int targ = TBuilder::calc_targ(prev_targ);
        using built_type = typename TBuilder::template type<targ>;

        // recurse
        using further_types = typename helper<targ, TBuilders2...>::type;

        // concatenate tuple
        using type = tuple_cat_types<std::tuple<built_type>, further_types>;
    };

    // concatenate tuple with First_mod
    using type = tuple_cat_types<std::tuple<First_mod<first_targ>>,
                     typename helper<first_targ, TBuilders...>::type>;
};


int main()
{
    gen<First_mod<3>, A_builder<5>, B_builder<2>>::type x;
    static_assert(std::tuple_size<decltype(x)>::value == 3, "!");
    std::get<0>(x).print();
    std::get<1>(x).print();
    std::get<2>(x).print();
}

您的公式、示例或N_mod的模板参数顺序错误。如果A_mod
A_mod
表示targ(1)=2,param(1)=5,那么A_mod的公式必须是targ(i)=param(i)-targ(i-1)。@DyP,是的,我错了。修正了。在写了东西并得到错误的输出后,我很担心;)(通常,如果这些东西是编译的,那么它们是正确的)我想如果第一种类型也有一个构建器(即使它什么都没有做),可能会简单一些。您可以去掉递归中的“特例”(专门化
gen
和元组的第二个连接类型定义)。请参阅使用
First\u builder
版本的“编辑我的答案”。您的公式、示例或N\u mod的模板参数顺序都是错误的。如果A_mod
A_mod
表示targ(1)=2,param(1)=5,那么A_mod的公式必须是targ(i)=param(i)-targ(i-1)。@DyP,是的,我错了。修正了。在写了东西并得到错误的输出后,我很担心;)(通常,如果这些东西是编译的,那么它们是正确的)我想如果第一种类型也有一个构建器(即使它什么都没有做),可能会简单一些。您可以去掉递归中的“特例”(专门化
gen
和元组的第二个连接类型定义)。请参阅对我的答案的编辑,以获得使用
First\u builder
的版本(我仍在评论/提供一些文档)。@gorill通常,您使用递归来处理此类事情。这里的具体技巧是:1)使构建器尽可能有用2)不要通过继承而递归,而是通过嵌套的typedef(能够使用静态成员和嵌套的typedef)3)连接元组(我仍在评论/提供一些文档。)@gorill通常,这类事情使用递归。这里的具体技巧是:1)使生成器尽可能有用2)不要通过继承递归,而是通过嵌套的typedef(能够使用静态成员和嵌套的typedef)3)连接元组