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()...
我仍然很想为以下情况找到(模板)解决方案:
- 所有
vec_0,...,vec_n
都是更大向量 Vec
的不同大小切片。
- 每个元组的大小信息也从元组中获知
所以实际上我需要的看起来如下
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));
}
考虑具有相似接口的 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)
我知道添加数字元组的元素,例如
std::get<0>(t).bar()+std::get<1>(t).bar()...
我仍然很想为以下情况找到(模板)解决方案:
- 所有
vec_0,...,vec_n
都是更大向量Vec
的不同大小切片。 - 每个元组的大小信息也从元组中获知 所以实际上我需要的看起来如下
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));
}