C++11:来自第二个元素的范围循环向量? [英] C++11: Range-looping vector from the second element?
问题描述
我有一个 std::vector
(已初始化).如何使用 range-for 循环访问除第一个元素(索引为零)以外的所有元素.对于所有元素:
I have a std::vector<std::string> v;
(initialized). How can I use the range-for loop for accessing all elements except the first one (on index zero). For all elements:
for (const string & s: v)
process(s);
可以使用范围表达式代替v
.如何编写范围表达式以跳过第一个元素(或跳过前n个元素)?
Instead of the v
a range expression can be used. How can I write the range expression to skip the first element (or skip the first n elements)?
我知道如何使用 v.begin() + 1
和经典循环来获得效果.我正在寻找新的、更易读的、推荐的替代方法来做到这一点.可能类似于 Python 切片?...喜欢:
I know how to get the effect using v.begin() + 1
and using the classic loop. I am searching for the new, more readable, recommended alternative to do that. Possibly something similar to Python slicing? ...like:
for s in v[1:]:
process(s)
推荐答案
创建一个包装器,使其 begin() 和 end() 返回正确的迭代器,然后您可以将其用作第二个参数.
Create a wrapper for which begin() and end() return the correct iterators and then you can use that as the second argument.
#include <iostream>
#include <vector>
template< typename Collection >
class FromNth
{
Collection& coll_;
size_t offset_;
public:
FromNth( Collection& coll, size_t offset )
: coll_( coll ), offset_( offset )
{
}
// will nicely resolve to const_iterator if necessary
auto begin() const -> decltype( coll_.begin() )
{ return coll_.begin() + offset_; }
auto end() const -> decltype( coll_.end() )
{ return coll_.end(); }
};
template< typename Collection >
FromNth<Collection> makeFromNth( Collection& collection, size_t offset )
{
return FromNth<Collection>( collection, offset );
}
template< typename Collection >
auto begin( const FromNth<Collection> & wrapper ) -> decltype( wrapper.begin() )
{
return wrapper.begin();
}
template< typename Collection >
auto end( const FromNth<Collection> & wrapper ) -> decltype( wrapper.end() )
{
return wrapper.end();
}
int main()
{
std::vector< int > coll { 2, 3, 5, 7, 11, 13, 17, 19, 23 };
for( auto x : makeFromNth( coll, 1 ) )
{
std::cout << x << '
';
}
return 0;
}
请注意,如果输入的大小小于偏移量,则我的 fromNth "begin" 是未定义的行为.(如果它相等,则它定义良好并且开始 == 结束).因此,请先检查尺寸.
Note that my fromNth "begin" is undefined behaviour if the size of the input is less than the offset. (If it's equal then it's well defined and begin == end). Therefore do a size check first.
注意:如果您使用的是最新版本的 boost,那么 iterator_range
可能已经为您提供了类似于我的FromNth"的集合".
Note: if you are using a recent enough version of boost then iterator_range
may already provide you such a "collection" that is similar to my "FromNth".
for( auto const& s : boost::make_iterator_range( v.begin() + 1, v.end() ) )
{
process( s );
}
注意:上述代码适用于使用 C++11 GNU 4.8.3 的 CodingGround.(虽然那个网站很慢).从 C++14 开始,您将不需要 ->decltype 语句(在 C++11 模板中需要这些语句).
Note: the code above worked on CodingGround using C++11 GNU 4.8.3. (That site is very slow though). From C++14 you will not need the ->decltype statements (which are needed in C++11 for templates).
输出:
sh-4.3$ g++ -std=c++11 -o main *.cpp
sh-4.3$ main
3
5
7
11
13
17
19
23
这篇关于C++11:来自第二个元素的范围循环向量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!