Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/148.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_Variadic Templates_C++17_Template Meta Programming - Fatal编程技术网

C++ 展平类型包,其中非类型值是展平的一部分

C++ 展平类型包,其中非类型值是展平的一部分,c++,templates,variadic-templates,c++17,template-meta-programming,C++,Templates,Variadic Templates,C++17,Template Meta Programming,如果您查看 template <typename Pack> struct flatten; template <typename T, typename U, std::size_t A, std::size_t B, std::size_t C, typename V, std::size_t D, std::size_t E, typename W> struct flatten<std::tuple<T,U, std::index_sequence&

如果您查看

template <typename Pack> struct flatten;

template <typename T, typename U, std::size_t A, std::size_t B, std::size_t C, typename V, std::size_t D, std::size_t E, typename W>
struct flatten<std::tuple<T,U, std::index_sequence<A,B,C>, V, std::index_sequence<D,E>, W>> {
    template <typename, typename, std::size_t, std::size_t, std::size_t, typename, std::size_t, std::size_t, typename> struct S;
    using type = S<T,U,A,B,C,V,D,E,W>;
};
如果非类型被包装在一个类型中,那么是否可以按常规方式将所有类型和非类型展平到一个展平的包中

这是我对正常类型展平的简单解决方案,我只是想知道如何使用这种方法来处理上述问题

template <typename T> struct identity { using type = T; };

template <typename...> struct merge;

template <typename Pack>
struct merge<Pack> : identity<Pack> {};

template <template <typename...> class P, typename... Ts, typename... Us>
struct merge<P<Ts...>, P<Us...>> : identity<P<Ts..., Us...>> {};

template <typename First, typename... Rest>
struct merge<First, Rest...> : merge<First, typename merge<Rest...>::type> {};

template <typename T, template <typename...> class P> struct flatten_h : identity<P<T>> {};

template <template <typename...> class P, typename... Ts>
struct flatten_h<P<Ts...>, P> : merge<typename flatten_h<Ts, P>::type...> {};   

template <typename Pack> struct flatten;

template <template <typename...> class P, typename... Ts>
struct flatten<P<Ts...>> : flatten_h<P<Ts...>, P> {};

// Testing
#include <type_traits>

template <typename...> struct P;

int main() {
    static_assert(std::is_same<
        flatten<P<int, char, long, P<double, bool>, int>>::type,
        P<int, char, long, double, bool, int>
    >::value);

    static_assert(std::is_same<
        flatten<P<int, P<bool, bool>, long, P<double, P<char, P<long>>>, int>>::type,
        P<int, bool, bool, long, double, char, long, int>
    >::value);
}

我认为C++20应该允许自动。。。或者其他一些关键字来指示模板参数的类型值和非类型值。

如果从std::index_序列解包的每个非类型参数都可以包装在自己的std::integral_常量中,则该任务变得可行。然后,在展开发生的级别上只有类型模板参数,可以使用简单的类型容器,如模板结构类型{}

下面是一个完整的工作示例,其中包含该限制和注释中提到的bug

我选择指定应该展平的所有类型。或者,也可以使用表单模板的各种模板参数等盲目地解包所有合理的内容

输出:

void inspect() [with T = Flattened<int, char, long int, Val<7>, double, Val<5>, float, unsigned int, Custom, char, int, Val<false>, Val<true>, Val<2>, Val<3>, Val<5>, Val<19>, Val<4>, Val<8> >]
具有较长类型名称的输出:

void inspect() [with T = Flattened<int, char, long int, std::integral_constant<int, 7>, double, std::integral_constant<int, 5>, float, unsigned int, Custom, char, int, std::integral_constant<bool, false>, std::integral_constant<bool, true>, std::integral_constant<long unsigned int, 2>, std::integral_constant<long unsigned int, 3>, std::integral_constant<int, 5>, std::integral_constant<long unsigned int, 19>, std::integral_constant<long unsigned int, 4>, std::integral_constant<int, 8> >]
void inspect() [with T = Flattened<int, char, long int, Val<7>, double, Val<5>, float, unsigned int, Custom, char, int, Val<false>, Val<true>, Val<2>, Val<3>, Val<5>, Val<19>, Val<4>, Val<8> >]
void inspect() [with T = Flattened<int, char, long int, std::integral_constant<int, 7>, double, std::integral_constant<int, 5>, float, unsigned int, Custom, char, int, std::integral_constant<bool, false>, std::integral_constant<bool, true>, std::integral_constant<long unsigned int, 2>, std::integral_constant<long unsigned int, 3>, std::integral_constant<int, 5>, std::integral_constant<long unsigned int, 19>, std::integral_constant<long unsigned int, 4>, std::integral_constant<int, 8> >]