什么是使用C++ 20范围删除最后一个元素的最佳方法
有没有比反转两次更好的方法来使用 c++20 范围删除容器中的最后一个元素?
#include <iostream>
#include <vector>
#include <ranges>
int main()
{
std::vector<int> foo{1, 2, 3, 4, 5, 6};
for (const auto& d: foo | std::ranges::views::reverse
| std::ranges::views::drop(1)
| std::ranges::views::reverse)
{
std::cout << d << std::endl;
}
}
Is there any better way to drop last element in container using c++20 ranges than reverse it twice?
#include <iostream>
#include <vector>
#include <ranges>
int main()
{
std::vector<int> foo{1, 2, 3, 4, 5, 6};
for (const auto& d: foo | std::ranges::views::reverse
| std::ranges::views::drop(1)
| std::ranges::views::reverse)
{
std::cout << d << std::endl;
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
您需要的是
views :: drop_last
来自 p2214 ,并具有第2层的优先级。作为纸说:
由于
vector
是一个随机访问,大小的范围,您只能做What you need is
views::drop_last
which comes from p2214 and has a priority of Tier 2.As the paper says:
Since
vector
is a random-access, sized range, you can just do使用
span
怎么样?How about using
span
?您可以通过以下方式进行良好的近似:
让您:
这不是一个完美的范围适配器,因为你不能写像 auto my_adaptor = transform(f) | 这样的东西drop_last; 为此,您需要 P2387,它是一个 C++23 库特征。在 C++23 中,您可以这样编写:
现在这是一个功能齐全的范围适配器。当前的 libstdc++ 特定版本看起来像这样(只是为了演示,实际上并不这样做 - 这这不是在 C++23 中执行此操作的方式)。
当然,这仅限于尺寸范围。这可能有各种各样的方向。您可以通过执行 std::ranges::distance(r) 来支持任何前向范围(以多次遍历为代价)。但定制实施可以做得更好。对于 bidi+common,您只需停在
prev(end(r))
处。仅对于前向,您可以一次前进两个迭代器,等等。只是需要考虑的事情。You can do a good approximation via:
That lets you:
This isn't a perfect range adaptor, since you can't write something like
auto my_adaptor = transform(f) | drop_last;
In order to do that, you need P2387, which is a C++23 library feature. In C++23, you'd write it this way:And now this is a completely functional range adaptor. The current libstdc++-specific version looks like this (just to demonstrate, don't actually do this - this isn't how you'd do this in C++23).
Of course, this is limited to sized ranges. There's all sorts of directions this could go. You could support any forward range by doing
std::ranges::distance(r)
instead (at the cost of multiple traversal). But a bespoke implementation could do better. For bidi+common, you just need to stop atprev(end(r))
. For forward only, you could advance two iterators at a time, etc. Just something to think about.您可以为此使用views::slide(2)。或视图::相邻<2>如果您更喜欢元组而不是范围。
如果你想删除两端,你可以使用views::slide(3)并从每个窗口中取出中间部分。
您可以将这些滑动窗口视为金字塔:

每个十字代表金字塔的顶部,并且可以被视为金字塔底部元素的窗口。
You can use views::slide(2) for this. Or views::adjacent<2> if you prefer tuples to ranges.
If you wanted to remove both ends, you could use views::slide(3) and take the middle from each window.
You can see these sliding windows as a pyramid:

each cross represents the top of a pyramid and can be seen as a window on the elements at the base of the pyramid.