我不知道如何将take与从容器中移除所获取的元素的操作巧妙地结合起来。
考虑一下下面是代码:
static constexpr int kBatchSize = 4;
void fn(std::deque<int>& vals) {
const auto elems = std::views::take(vals, kBatchSize);
fmt::print("\n[");
for (const auto& elem : elems) {
fmt::print("{} ", elem);
}
fmt::print("]\n");
for ([[maybe_unused]] const auto&_:elems) {
vals.pop_front();
}
}它工作得很好(AFAIK),但我需要额外的迭代,因为我无法找到一种将元素的提取和删除结合起来的方法。
注意:fmt::print只是每个元素逻辑的一个例子,请不要关注这样一个事实,即这可以以更好的方式完成。在实际的代码函数中,不是简单的打印。
是否有一种优雅的方法将其合并成一次传递?
发布于 2022-07-30 19:36:38
视图不能修改容器;它们的任务是成为范围的视图。
如果您只想遍历第一个X元素,然后删除所有元素(除非您想要复制这些元素,它就必须按照这个顺序进行),那么使用std::for_each_n很容易做到这一点
void fn(std::deque<int>& vals)
{
fmt::print("\n[");
auto end_it = std::for_each_n(vals.begin(), kBatchSize, [](int const& elem){
fmt::print("{} ", elem);
});
fmt::print("]\n");
vals.erase(vals.begin(), end_it);
}发布于 2022-07-30 20:03:36
您可以在不修改vals的情况下做到这一点。例如,通过将vals转换为subrange并将每次时间分配给subrange:
#include <deque>
#include <ranges>
#include <fmt/ranges.h>
static constexpr int kBatchSize = 4;
auto fn(std::ranges::view auto vals) {
const auto elems = std::views::take(vals, kBatchSize);
fmt::print("{}\n", elems);
return vals | std::views::drop(kBatchSize);
}
int main() {
std::deque vals{1,2,3,4,5,6};
auto res = fn(std::ranges::subrange{vals}); // [1, 2, 3, 4]
res = fn(res); // [5, 6]
res = fn(res); // []
}之所以可以这样做,是因为std::views::take和std::views::drop对subranges有专门化,这要归功于P1739,也就是说,它们返回一个大小正确的subrange。
https://stackoverflow.com/questions/73178117
复制相似问题