gpt4 book ai didi

c++ - 转换嵌套包的每个内部包

转载 作者:搜寻专家 更新时间:2023-10-31 02:24:13 24 4
gpt4 key购买 nike

在这里,作为示例,我将尝试将包中的模板参数向左旋转 N,但我希望对嵌套包的每个内部包也这样做。下面的代码仅在该内部包是包中的第一种类型时才有效,我需要知道如何检查包中的每种类型(如果它是嵌套的)然后将转换应用于每种类型。 TransformNestedPack 是我正在做的事情。 PackTransformation 的原因是 TransformNestedPack 可以重复用于任何转换(旋转只是我使用的示例)。所以我正在尝试使用通用转换 PackTransformation 来完善 TransformNestedPack

#include <iostream>

// Rotating a pack N to the left.
template <int, typename> struct Rotate;

template <template <typename...> class P, typename First, typename... Rest>
struct Rotate<0, P<First, Rest...>> {
using type = P<First, Rest...>;
};

template <int N, int K>
struct PositiveModulo : std::integral_constant<int, (N % K + K) % K> {};

template <int N, template <typename...> class P, typename First, typename... Rest>
struct Rotate<N, P<First, Rest...>> :
Rotate<PositiveModulo<N-1, sizeof...(Rest)+1>::value, P<Rest..., First>> {};

enum {Rot, Rev, /* ... */}; // enum values for each type of pack transformation.

template <typename, int, int...> struct PackTransformation;

// Specializations of PackTransformation to carry out each type of pack transformation.
template <template <typename...> class P, int N, typename... Types>
struct PackTransformation<P<Types...>, Rot, N> {
using type = typename Rotate<N, P<Types...>>::type;
};
// Similarly struct PackTransformation<P<Types...>, Rev> will reverse P<Types...>, etc...

// Attempt to have PackTransformation applied to each inner pack in a nested pack:
template <typename, int, int...> struct TransformNestedPack;

// Normal transformation, because the first type is not a pack:
template <template <typename...> class P, typename... Types, int N, int... Parameters>
struct TransformNestedPack<P<Types...>, N, Parameters...> : PackTransformation<P<Types...>, N, Parameters...> {};

// Specialization for when the first type is a pack:
template <template <typename...> class P, typename... Types, typename... Rest, int N, int... Parameters>
struct TransformNestedPack<P<P<Types...>, Rest...>, N, Parameters...> :
PackTransformation<P<typename TransformNestedPack<P<Types...>, N, Parameters...>::type, Rest...>, N, Parameters...> {};
// The problem above is that it checks only the first type. It needs to check EVERY type.

template <typename...> struct Pack {};

int main() {
using NestedPack = Pack<Pack<int, double, char, long>, char, long, short>;
PackTransformation<NestedPack, Rot, 2>::type a; // Rotates NestedPack to the left by 2, but not the inner pack.
std::cout << std::boolalpha << std::is_same< decltype(a),
Pack<long, short, Pack<int, double, char, long>, char>
>::value << std::endl; // true

TransformNestedPack<NestedPack, Rot, 2>::type b;
std::cout << std::is_same< decltype(b),
Pack<long, short, Pack<char, long, int, double>, char>
>::value << std::endl; // true
// The above currently works only if there is one nested pack and that nested pack is the first type.
}

我只需要通过检查每个类型是否是一个包来概括以上内容,而不仅仅是第一个。

最佳答案

首先,不要让 TransformNestedPack 的主模板未定义,如果它不是包,则让它返回类型不变:

template <typename T, int, int...> struct TransformNestedPack {
using type = T; // do nothing for non-packs
};

然后转换包包括 1) 递归地将 TransformNestedPack 应用于包中的每个类型,以及 2) 将 PackTransformation 应用于转换类型本身的结果包。因此:

template <template <typename...> class P, typename... Types, int N, int... Parameters>
struct TransformNestedPack<P<Types...>, N, Parameters...>
: PackTransformation<P<typename TransformNestedPack<Types, N, Parameters...>::type...>,
N, Parameters...> {};

Demo .

关于c++ - 转换嵌套包的每个内部包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28325544/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com