std:tuple 中对象中元素的复杂求和

sophisticated summation of elements in objects residing in a std:tuple

考虑具有相似接口的 n 个对象的元组 t(就像所有对象都具有相同的基 class); n 在编译期间已知。我需要做如下总结

std::get<0>(t).foo(vec_0) + std::get<1>(t).foo(vec_1) + ... + std::get<n>(t).foo(vec_n)

我知道添加数字元组的元素,例如 ,甚至是元组中对象的 variable\functions,例如

std::get<0>(t).bar()+std::get<1>(t).bar()...

我仍然很想为以下情况找到(模板)解决方案:

  1. 所有 vec_0,...,vec_n 都是更大向量 Vec 的不同大小切片。
  2. 每个元组的大小信息也从元组中获知 所以实际上我需要的看起来如下
std::get<0>(t).foo(Vec.head(std::get<0>(t).n)) + 
std::get<1>(t).foo(Vec.segment(std::get<0>(t).n, std::get<1>(t).n))+
std::get<2>(t).foo(Vec.segment(std::get<0>(t).n + std::get<1>(t).n, std::get<2>(t).n))+
... +
std::get<n>(t).foo(Vec.tail(std::get<n>(t).n))

这里segment需要(start, size)和return需要的向量;大小从 std::get<?>(t).n.

中得知

您只需要额外 std::index_sequence 内部元素的用法,例如:

template <std::size_t ... Is, typename Tuple, typename Vec>
auto helper(std::index_sequence<Is...>, const Tuple& t, const Vec& vec)
{
    constexpr auto N = sizeof...(Is);
    constexpr auto Size = std::tuple_size<Tuple>::value;

    if constexpr (Size == 1) {
        // Unsure what you want here
        return std::get<0>(t).foo(Vec.head(std::get<0>(t).n))
             + std::get<N>(t).foo(Vec.tail(std::get<0>(t).n));
    } else if constexpr (N == 0) {
        return std::get<0>(t).foo(Vec.head(std::get<0>(t).n)); 
    } else if constexpr (N + 1 == Size) {
        return std::get<N>(t).foo(Vec.tail(std::get<N>(t).n));
    } else {
        return std::get<N>(t).foo(Vec.segment((0 + ... + std::get<Is>(t).n),
                                              std::get<N>(t).n));
    }
}

template <std::size_t ... Is, typename Tuple, typename Vec>
auto summation(std::index_sequence<Is...>, const Tuple& t, const Vec& vec)
{
    return (0 + ... + helper(std::make_index_sequence<Is>(), t, vec));
}

template <typename Tuple, typename Vec>
auto summation(const Tuple& t, const Vec& vec)
{
    constexpr auto Size = std::tuple_size<Tuple>::value;
    return summation(std::make_index_sequence<Size>(), t, vec));
}