Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/153.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/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
C++ 转换嵌套包的每个内部包_C++_Templates_Variadic - Fatal编程技术网

C++ 转换嵌套包的每个内部包

C++ 转换嵌套包的每个内部包,c++,templates,variadic,C++,Templates,Variadic,这里,作为一个例子,我将尝试将包中的模板参数向左旋转N,但我希望对嵌套包的每个内部包也这样做。下面的代码仅在内部包是包中的第一个类型时有效,我需要知道如何检查包中的每个类型(如果它是嵌套的),然后将转换应用于每个类型TransformNestedPack是我正在研究的。PackTransformation的原因是TransformNestedPack可以在任何转换中重用(旋转只是我使用的一个示例)。因此,我尝试使用常规转换PackTransformation来完善TransformNestedP

这里,作为一个例子,我将尝试将包中的模板参数向左旋转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.
}
#包括
//向左旋转一个包N。
模板结构旋转;
模板
结构旋转{
使用类型=P;
};
模板
结构正模块:std::积分常数{};
模板
结构旋转:
旋转{};
枚举{Rot,Rev,/*…*/};//每种包转换类型的枚举值。
模板结构包转换;
//包装转换的专业化,以执行每种类型的包装转换。
模板
结构包转换{
使用type=typename旋转::type;
};
//类似地,结构包转换将反转P等。。。
//尝试将PackTransformation应用于嵌套包中的每个内部包:
模板结构转换嵌套包;
//正常转换,因为第一种类型不是包:
模板
struct TransformNestedPack:PackTransformation{};
//第一种类型为包时的专用化:
模板
结构转换嵌套包:
包装转换{};
//上面的问题是它只检查第一种类型。它需要检查每种类型。
模板结构包{};
int main(){
使用NestedPack=Pack;
PackTransformation::type a;//将嵌套包向左旋转2,但不旋转内部包。

std::cout首先,不要让
TransformNestedPack
的主模板未定义,而是让它在不是包的情况下返回不变的类型:

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

.

看起来像是对某些编译器模板引擎的单元测试。当然,这个优秀的解决方案得到了我的投票。但它不适用于不同的包模板。例如,当我尝试反转
pack
时,我没有得到所需的
pack
。我的旋转示例也存在同样的问题。这就是使用解决方案中的模板模板
P
。@prestokeys它可以很好地处理不同的包类型。问题是,您的代码将
std::string
视为一个包,并反转/旋转其模板参数;我只是照着做。好的,用另一个专门化
struct TransformNestedPack摆脱了该部分{using type=std::string;};
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...> {};