c++ - C++:使用 std::apply 在 2 部分中迭代元组:直到应用 lambda 的索引,然后在应用不同 lambda 的索引之后
问题描述
如果我想使用但不将一个函数应用于整个事物来遍历一个元组std::apply
,我该如何分离元组,即将一个函数应用于第一个n
值,另一个应用于它之后的所有值?
some_values
将是一个元组,它可以具有任何长度和类型,并且length_of_first_part
(可能命名得不那么冗长)在编译时就知道了。
std::tuple<char, long long, double, long double, float> some_values(33, 2, 3.4, 5.6, 7.8);
const size_t length_of_first_part = 2;
std::apply(
[](auto&&... current_val) {
((std::cout << "(Should be first part) " << current_val << "\n"), ...); //Would obviously do a litle more than cout, but this is just a minimal example
}, some_values
);
std::apply(
[](auto&&... current_val) {
((std::cout << "(Should be second part) " << current_val << "\n"), ...);
}, some_values
);
解决方案
试一试。在这里查看“可能的实现”: https ://en.cppreference.com/w/cpp/utility/apply
它将一个传递std::index_sequence
给一个辅助函数来调用std::invoke
。我将其更改为通过std::make_sequence<N>
(N 是拆分索引)而不是元组大小。然后我通过逆(元组大小 - N)来调用std::invoke
第二个函数:
template <int N, typename F1, typename F2, typename Tuple, size_t... I1s, size_t... I2s>
decltype(auto) split_apply_impl(F1&& f1, F2&& f2, Tuple&& t, std::index_sequence<I1s...>, std::index_sequence<I2s...>) {
std::invoke(std::forward<F1>(f1), std::get<I1s>(std::forward<Tuple>(t))...);
return std::invoke(std::forward<F2>(f2), std::get<(I2s+N)>(std::forward<Tuple>(t))...);
}
template <size_t N, typename F1, typename F2, typename Tuple>
decltype(auto) split_apply(F1&& f1, F2&& f2, Tuple&& t)
{
return split_apply_impl<N>(
std::forward<F1>(f1),
std::forward<F2>(f2),
std::forward<Tuple>(t),
std::make_index_sequence<N>{},
std::make_index_sequence<(std::tuple_size_v<std::remove_reference_t<Tuple>>-N)>{});
}
用法:
std::tuple<char, long long, double, long double, float> some_values(33, 2, 3.4, 5.6, 7.8);
constexpr size_t length_of_first_part = 2;
split_apply<length_of_first_part>(
[](auto&&... current_val) {
((std::cout << "(Should be first part) " << current_val << "\n"), ...);
},
[](auto&&... current_val) {
((std::cout << "(Should be second part) " << current_val << "\n"), ...);
},
some_values);
推荐阅读
- javascript - 尝试设置前端时收到以下语法错误
- excel - 如何根据第一个和最后一个文件名将100个文件复制到一个文件夹并在列表框vba中显示
- ngxs - 刷新浏览器选项卡后保留状态
- ios - 带有交叉溶解动画的 swift UIPageViewController
- javascript - 我可以根据浏览器的缩放调整图像大小吗?
- mobile - 有没有其他方法可以改变脚手架抽屉的宽度?
- spring-boot - “状态”:403,“错误”:“禁止”,“消息”:“禁止”,“路径”:“/post/create”
- node.js - 从 mysql 安全/验证 Node js-Express Rest api 的方法
- python - 给定一个图(或元图)(但没有 TF 事件文件),如何可视化它
- php - RouteServiceProvider 中的 Laravel 显式路由模型绑定问题