std::tuple
需要将操作应用于
std::tuple
"zip iterator"
底层范围和迭代器存储在
std::tuple
std::index_sequence<std::tuple_size<Tuple>>
为了得到相关的元素,它似乎使用了在
std::tuple
std::tuple
-类似结构(例如:。,
std::array
或
std::pair
)可以改进代码。
tuple_for_each()
std::index_sequence
要应用这些元素:
template <typename Tuple, typename Fun>
void tuple_for_each(Tuple&& tuple, Fun fun)
{
auto const impl = [&tuple, fun]<std::size_t...I>(std::index_sequence<I...>){
(fun(std::get<I>(tuple)), ...);
};
impl(std::make_index_sequence<std::tuple_size_v<std::decay_t<Tuple>>>());
}
当操作不是真正的元素智能化时
for_each
transform
accumulate
或
inner_product
.在自定义设置中,这些可以很容易地编写,例如:。,
template <typename... T>
struct some_struct {
std::tuple<T...> tuple;
template <typename Tuple, std::size_t... I>
static bool equals(Tuple&& t0, Tuple&& t1, std::index_sequence<I...>) {
return ((std::get<I>(t0) == std::get<I>(t1)) && ...);
}
bool operator== (some_struct const& other) const {
return equals(this->tuple, other.tuple, std::make_index_sequence<sizeof...(T)>());
}
};
operator==()
可以委托给合适的
tuple
算法:
bool operator== (some_struct const& other) const {
return tuple_inner_product(this->tuple, other.tuple, true, std::equal_to<>(), std::logical_and<>());
}
tuple_inner_product
使用折叠表达式,而不是基于最后一个参数的类型创建特殊版本。我知道如何实现递归版本,但我不认为如果合并操作是逻辑操作数之一,该版本会缩短求值过程(在调用函数之前,始终需要确定函数参数):
template <typename T0, typename T1, typename Init, typename Transform, typename Combine>
auto tuple_inner_product(T0&& t0, T1&& t1, Init init, Transform transform, Combine combine) {
auto const recurse = [&t0, &t1, transform, combine]<std::size_t I>(
std::integral_constant<std::size_t, I>,
auto const& r, auto init) {
if constexpr (I == std::min(std::tuple_size_v<std::decay_t<T0>>,
std::tuple_size_v<std::decay_t<T1>>)) {
return init;
}
else {
return combine(transform(std::get<I>(t0), std::get<I>(t1)),
r(std::integral_constant<std::size_t, I+1>(), r, init));
}
};
return recurse(std::integral_constant<std::size_t, 0u>(), recurse, init);
}
因此,问题变成了是否有一种方法可以使用折叠表达式来实现该算法?