如果你接受通过
Q<>
而不是
Q
和
std::integer_sequence<int>
(或
std::integer_sequence<std::size_t>
)而不是
std::integer_sequence
(因此使用模板类型而不是模板类型)您可以在底部分叉案例(有或没有第一个类型模板)(请参见
accumulated_h2
所以你可以使用
accumulated
对于这两种情况,都要离开
accumulated_sum
.
下面是一个完整的工作示例。
#include <type_traits>
#include <utility>
namespace detail
{
template <typename Pack>
struct sequence_traits;
template <typename T, template <T...> class Z, T... Is>
struct sequence_traits<Z<Is...>>
{ using templ_empty = Z<>; };
}
// accumulated
template <typename T, typename, T...>
struct accumulated_h2;
template <typename T, template <typename, T ...> class Q, T ... Ts>
struct accumulated_h2<T, Q<T>, Ts...>
{ using type = Q<T, Ts...>; };
template <typename T, template <T ...> class Q, T ... Ts>
struct accumulated_h2<T, Q<>, Ts...>
{ using type = Q<Ts...>; };
template <typename T, typename, typename, T...>
struct accumulated_h;
template <typename T, template <T...> class Z, typename C, T Sum, T... Is>
struct accumulated_h<T, Z<Sum, Is...>, C>
{ using type = typename accumulated_h2<T, C, Is..., Sum>::type; };
template <typename T, template <T...> class Z, T Sum, T... Is,
typename C, T Next, T... Rest>
struct accumulated_h<T, Z<Sum, Is...>, C, Next, Rest...>
: accumulated_h<T, Z<Sum + Next, Is..., Sum>, C, Rest...>
{ };
template <typename T,
typename = typename detail::sequence_traits<T>::templ_empty>
struct accumulated;
template <typename T, template <T...> class Z, T First,
T... Rest, typename C>
struct accumulated<Z<First, Rest...>, C>
: accumulated_h<T, Z<First>, C, Rest...>
{ };
// Testing
template <int...>
struct Z;
template <int...>
struct Q;
template <std::size_t...>
struct I;
int main ()
{
static_assert(std::is_same<
accumulated<Z<1,2,3,4,5>, Q<>>::type,
Q<1,3,6,10,15>>::value, "!");
static_assert(std::is_same<
accumulated<Z<1,2,3,4,5>>::type,
Z<1,3,6,10,15>>::value, "!");
static_assert(std::is_same<
accumulated<Z<1,2,3,4,5>, std::integer_sequence<int>>::type,
std::integer_sequence<int, 1,3,6,10,15>>::value, "!");
static_assert(std::is_same<
accumulated<I<1,2,3,4,5>, std::integer_sequence<std::size_t>>::type,
std::index_sequence<1,3,6,10,15>>::value, "!");
}
--编辑--
OP提问
以及如何分叉箱子,以便
accumulated<std::integer_sequence<T, 1,2,3,4,5>>::type
是
std::integer_sequence<T, 1,3,6,10,15>
哪里
T
有积分类型吗?
我看到了你的解决方案,我准备了另一个,没什么不同:扔掉旧的
Z
,我用
std::整数_序列
相反,你的
squeeze
.
以下是我的代码。
#include <type_traits>
#include <utility>
namespace detail
{
template <typename Pack>
struct sequence_traits;
template <typename T, template <typename, T...> class Z, T... Is>
struct sequence_traits<Z<T, Is...>>
{ using templ_empty = Z<T>; };
template <typename T, template <T...> class Z, T... Is>
struct sequence_traits<Z<Is...>>
{ using templ_empty = Z<>; };
}
// accumulated
template <typename T, typename, T...>
struct accumulated_h2;
template <typename T, template <typename, T ...> class Q, T ... Ts>
struct accumulated_h2<T, Q<T>, Ts...>
{ using type = Q<T, Ts...>; };
template <typename T, template <T ...> class Q, T ... Ts>
struct accumulated_h2<T, Q<>, Ts...>
{ using type = Q<Ts...>; };
template <typename T, typename, typename, T...>
struct accumulated_h;
template <typename T, typename C, T Sum, T... Is>
struct accumulated_h<T, std::integer_sequence<T, Sum, Is...>, C>
{ using type = typename accumulated_h2<T, C, Is..., Sum>::type; };
template <typename T, T Sum, T... Is, typename C, T Next, T... Rest>
struct accumulated_h<T, std::integer_sequence<T, Sum, Is...>, C, Next,
Rest...>
: accumulated_h<T, std::integer_sequence<T, Sum + Next, Is..., Sum>,
C, Rest...>
{ };
template <typename T,
typename = typename detail::sequence_traits<T>::templ_empty>
struct accumulated;
template <typename T, template <T...> class Z, T First,
T... Rest, typename C>
struct accumulated<Z<First, Rest...>, C>
: accumulated_h<T, std::integer_sequence<T, First>, C, Rest...>
{ };
template <typename T, template <typename, T...> class Z, T First,
T... Rest, typename C>
struct accumulated<Z<T, First, Rest...>, C>
: accumulated_h<T, std::integer_sequence<T, First>, C, Rest...>
{ };
// Testing
template <int...>
struct Z;
template <int...>
struct Q;
template <std::size_t...>
struct I;
int main ()
{
static_assert(std::is_same<
accumulated<Z<1,2,3,4,5>, Q<>>::type,
Q<1,3,6,10,15>>::value, "!");
static_assert(std::is_same<
accumulated<Z<1,2,3,4,5>>::type,
Z<1,3,6,10,15>>::value, "!");
static_assert(std::is_same<
accumulated<Z<1,2,3,4,5>, std::integer_sequence<int>>::type,
std::integer_sequence<int, 1,3,6,10,15>>::value, "!");
static_assert(std::is_same<
accumulated<I<1,2,3,4,5>, std::integer_sequence<std::size_t>>::type,
std::index_sequence<1,3,6,10,15>>::value, "!");
static_assert(std::is_same<
accumulated<std::index_sequence<1,2,3,4,5>>::type,
std::index_sequence<1,3,6,10,15>>::value);
static_assert(std::is_same<
accumulated<std::index_sequence<1,2,3,4,5>, I<>>::type,
I<1,3,6,10,15>>::value);
}