【发布时间】:2025-11-27 00:35:03
【问题描述】:
假设你有类似的东西
template <typename, typename, int, typename, int, typename...> struct P
并且您只想反转typename... 部分。现在您已经编写了通用反向转换:
// Reverse<Pack<Types...>>::type is Pack<Types'...>, where Types'... is Types... reversed.
template <typename, typename> struct ReverseHelper;
template <template <typename...> class P, typename Pack>
struct ReverseHelper<P<>, Pack> {
using type = Pack;
};
template <template <typename...> class P, typename First, typename... Rest, typename... Types>
struct ReverseHelper<P<First, Rest...>, P<Types...>> : ReverseHelper<P<Rest...>, P<First, Types...>> {};
template <typename> struct Reverse;
template <template <typename...> class P, typename... Types>
struct Reverse<P<Types...>> : ReverseHelper<P<Types...>, P<>> {};
当然,我们可以改写成template <typename, typename, int, typename, int, typename...> class P,即:
template <typename, typename> struct ReverseHelper1;
template <template <typename, typename, int, typename, int, typename...> class P,
typename U, typename V, int M, typename W, int N, typename Pack>
struct ReverseHelper1<P<U,V,M,W,N>, Pack> {
using type = Pack;
};
template <template <typename, typename, int, typename, int, typename...> class P,
typename U, typename V, int M, typename W, int N, typename First, typename... Rest, typename... Types>
struct ReverseHelper1<P<U,V,M,W,N, First, Rest...>, P<Types...>> : ReverseHelper<P<U,V,M,W,N, Rest...>, P<First, Types...>> {};
template <typename> struct Reverse1;
template <template <typename, typename, int, typename, int, typename...> class P,
typename U, typename V, int M, typename W, int N, typename... Types>
struct Reverse1<P<U,V,M,W,N, Types...>> : ReverseHelper1<P<U,V,M,W,N, Types...>, P<U,V,M,W,N>> {};
注意到我们只是在重复吗?然后,如果我们想做同样的部分反转事情,我们将不得不对其他模板签名一次又一次地这样做。那么如何通过使用原始的Reverse本身来避免所有这些重复呢?
例如,假设我们有
template <typename> struct Foo;
template <typename> struct Bar;
template <template <typename, typename, int, typename, int, typename...> class P,
typename U, typename V, int M, typename W, int N, typename... Args>
struct Foo<P<U,V,M,W,N, Args...>> {};
让我们让Foo<P<U,V,M,W,N, Args...>> 派生自Bar<P<U,V,M,W,N, ArgsReversed...>>。如何使用上面定义的Reverse 来完成此操作?
注意,和
template <template <typename, typename, int, typename, int, typename> class P,
typename U, typename V, int M, typename W, int N,
template <typename...> class Q, typename... Args>
struct Foo<P<U,V,M,W,N, Q<Args...>>> : Bar<P<U,V,M,W,N, typename Reverse<Q<Args...>>::type>> {};
虽然我怀疑完成它是按照这种方式完成的。当然,倒车只是一个例子。我们希望重用任何转换,以便仅对(任何)较大模板结构的一部分进行相同的转换。
【问题讨论】:
-
如果你打算使用元元程序,请使用
std::integral_constant和其他类型的常量包装器。 -
基于宏的解决方案可以吗?
-
@Yakk。如果宏是确定它的唯一方法。但我认为有办法只使用模板。
标签: c++ templates c++11 variadic