区分两个包扩展

Differentiate between two pack expansions

有没有办法明确指定哪个 ... 指的是哪个扩展包?在我的代码中,我有两个我想在不同级别应用的包扩展:

template<typename T, int N>
struct MyArr
{
    T e[N];

    constexpr T& operator[](int i) { return e[i]; }
    constexpr const T& operator[](int i) const { return e[i]; }

    MyArr() : e{} {}
    template<typename ...type_pack>
    MyArr(const type_pack&... pack) : e{pack...}
    {
        static_assert(sizeof...(pack)==N, 
        "Argument count must match the size.");
    }
};

template<typename type_lhs, typename type_rhs>
auto add(const type_lhs& lhs, const type_rhs& rhs)
{
    return lhs + rhs;
}

template<int ...I, typename type_head, typename ...type_pack, int N, typename Function>
auto apply(Function&& op, 
const MyArr<type_head,N>& head, const MyArr<type_pack,N>&... pack)
{
    return MyArr<type_head,N>((op(head[I],(pack[I])...))...);
    //                              expand pack[I]- ^ ,  ^ - expand I...
};

int main()
{
    MyArr<int,3> a(1,2,3);
    return apply<0,1,2>(add<int,int>, a, a);
}

本质上,我想得到:

(op(head[0], get<0>(pack)[0], ..., get<M-1>(pack)[0]),
 ..., 
 op(head[N-1], get<0>(pack)[N-1], ..., get<M-1>(pack)[N-1]))

感谢 OznOg 的建议,我通过在中间创建一个函数让它工作:

template<int ...I, typename type_head, typename ...type_pack, int N, typename Function>
auto apply(Function&& op, 
const MyArr<type_head,N>& head, const MyArr<type_pack,N>&... pack)
{
    auto op2 = [&](int i) { return op(head[i], pack[i]...);};
    return MyArr<type_head,N>(op2(I)...);
};

在这种特殊情况下,我看到的唯一方法是使用辅助函数(getVal(),在以下示例中)

template <int I, typename type_head, typename ...type_pack, int N,
          typename Function>
auto getVal (Function&& op, MyArr<type_head,N> const & head,
             MyArr<type_pack,N> const & ... pack)
 { return op(head[I], pack[I]...); }

template <int ... Is, typename type_head, typename ...type_pack, int N,
          typename Function>
auto apply (Function && op, MyArr<type_head,N> const & head,
            MyArr<type_pack,N> const &... pack)
 { return MyArr<type_head,N>{ getVal<Is>(op, head, pack...)... }; }

问题是你有

(pack[I])...

所以(据我所知)没有办法说扩展适用于 pack 而不是 I.

有中间函数

//.......................VVV  expand pack
getVal<Is>(op, head, pack...)...
//...........................^^^  expand Is

您可以使用括号来分隔级别。

但是你必须把packIs分开。