将argpack分成两半? [英] Splitting argpack in half?

查看:54
本文介绍了将argpack分成两半?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

How can I split an argument pack in two equal parts?

例如,我想执行以下操作:

For example, I would like to do something like this:

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)...); }


推荐答案

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

I would suggest something along the lines of this, as the required nesting depth and amount of boilerplate code is lower than in the suggested solution. However, the actual parameter pack is never split, instead two ranges of indices are produced to index the input values which are forwarded as tuples to be then accessed via std::get. Aside from the nesting depth, it is far easier to specify how the splitting is performed (rounding up, down, or taking a power of two and the remainder).

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)...)
    );
}

这需要

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;
};

这篇关于将argpack分成两半?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆