拆分argpack一半?

Sta*_*ked 25 c++ templates variadic-templates c++11

如何将参数包拆分为两个相等的部分?

例如,我想做这样的事情:

template<typename T> T sum(const T& t)
{ return t; }

template<typename T> T sum(const T& t1, const T& t2)
{ return t1 + t2; }

template<typename ...T> T sum(T&& ...t)
{ sum(first_half(t)...) + sum(second_half(t)...); }
Run Code Online (Sandbox Code Playgroud)

Joe*_*Joe 4

我会提出类似的建议,因为所需的嵌套深度和样板代码数量低于建议的解决方案。然而,实际的参数包永远不会被分割,而是生成两个索引范围来索引输入值,这些输入值作为元组转发,然后通过 std::get 访问。除了嵌套深度之外,指定如何执行拆分(向上舍入、向下舍入或取 2 的幂和余数)要容易得多。

int sum(int a) { return a; }
int sum(int a, int b) { return a + b; }

template<typename... Args> int sum(Args&&... args);

template<typename Tuple, size_t... index>
int sum_helper(pack_indices<index...>, Tuple&& args)
{
    return sum(std::get<index>(args)...);
}

template <size_t begin, size_t end, typename... Args>
int sum_helper(Args&&... args)
{
    typename make_pack_indices<end, begin>::type indices;
    return sum_helper(indices, std::forward_as_tuple(std::forward<Args>(args)...));
}

template<typename... Args>
int sum(Args&&... args)
{
    constexpr size_t N = sizeof...(Args);
    return sum(
        sum_helper<0, N/2>(std::forward<Args>(args)...),
        sum_helper<N/2, N>(std::forward<Args>(args)...)
    );
}
Run Code Online (Sandbox Code Playgroud)

这需要

template <size_t...>
struct pack_indices {};

template <size_t Sp, typename IntPack, size_t Ep>
struct make_indices_imp;

template <size_t Sp, size_t Ep, size_t... Indices>
struct make_indices_imp<Sp, pack_indices<Indices...>, Ep>
{
    typedef typename make_indices_imp<Sp+1, pack_indices<Indices..., Sp>, Ep>::type type;
};

template <size_t Ep, size_t... Indices>
struct make_indices_imp<Ep, pack_indices<Indices...>, Ep>
{
    typedef pack_indices<Indices...> type;
};

template <size_t Ep, size_t Sp = 0>
struct make_pack_indices
{
    static_assert(Sp <= Ep, "make_tuple_indices input error");
    typedef typename make_indices_imp<Sp, pack_indices<>, Ep>::type type;
};
Run Code Online (Sandbox Code Playgroud)