我想遍历一个容器(例如std::vector
),但不要从头开始。我基本上是在尝试复制boost::make_iterator_range(v.begin() + 1, v.end())
。
我想到了这个
#include <vector>
#include <iostream>
#include <algorithm>
int main()
{
std::vector<int> v {1, 2, 3};
std::for_each_n(v.begin() + 1, v.size() - 1, [](auto& n)
{
std::cout << n << '\n';
});
}
但是,这似乎是一个糟糕的解决方案。当我在寻找适用于C ++ 14的解决方案时,它也需要C ++ 17。
在没有第三方库的情况下,有没有更好的方法来实现这一目标?
答案 0 :(得分:2)
std::for_each
在C ++ 11中,您可以这样做:
std::for_each(v.begin() + 1, v.end(), [](auto &n) { ... });
答案 1 :(得分:2)
要复制make_iterator_range
,您需要一个具有begin
和end
函数的对象。像这样的东西。
template <typename T>
struct iterator_range {
iterator_range(T begin, T end) : m_begin(begin), m_end(end) {}
T begin() {
return m_begin;
}
T end() {
return m_end;
}
T m_begin, m_end;
};
然后,我们可以使我们的make_iterator_range
函数返回一个iterator_range
。
#include <vector>
#include <iostream>
template <typename T>
struct iterator_range {
iterator_range(T begin, T end) : m_begin(begin), m_end(end) {}
T begin() {
return m_begin;
}
T end() {
return m_end;
}
T m_begin, m_end;
};
template <typename T>
auto make_iterator_range(T begin, T end) {
return iterator_range<T>(begin, end);
}
int main()
{
std::vector<int> v {1, 2, 3};
auto range = iterator_range<decltype(v.begin())>(v.begin() + 1, v.end());
for (auto& i : range) {
std::cout << i << '\n';
}
for (auto& i : make_iterator_range(v.begin() + 1, v.end())) {
std::cout << i << '\n';
}
}
答案 2 :(得分:2)
有没有更好的方法来实现这一目标...
使用范围的解决方案(由cigien提供):
for (int element : v | ranges::drop_view(1))
使用span
for (int element : span(&v[1], v.size() - 1))
当然,直到C ++ 20都没有std::ranges
或std::span
,因此除非您想使用第三方实现,否则需要编写自己的实现。
如果您不想实现自己的库,也不能使用C ++ 20,也不想使用第三方库,请std::for_each
在C ++ 11中。 >