C ++ 11:第二个元素的范围循环矢量? [英] C++11: Range-looping vector from the second element?
问题描述
我有一个 std :: vector< std :: string> v;
(初始化)。如何使用range-for循环访问除第一个元素之外的所有元素(在索引零处)。对于所有元素:
$ b $ pre $ for(const string& s:v)
process(s);
而不是 v
a 可以使用范围表达式。 如何可以写范围表达式来跳过第一个元素(或者跳过前n个元素)??
我知道如何使用 v.begin()+ 1
并使用经典循环来获得效果。我正在寻找新的,更具可读性,推荐的替代方案。可能类似于Python切片的东西? ...例如:
$ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $
创建一个封装,begin()和end迭代器,然后你可以使用它作为第二个参数。
#include< iostream>
#include< vector>
模板< typename Collection>
class FromNth
{
Collection& coll_;
size_t offset_;
public:
FromNth(Collection& coll,size_t offset)
:coll_(coll),offset_(offset)
{
}
//很好的解析为const_iterator,如果需要的话
auto begin()const - > decltype(coll_.begin())
{return coll_.begin()+ offset_; }
auto end()const - > decltype(coll_.end())
{return coll_.end(); }
};
模板< typename Collection>
FromNth< Collection> makeFromNth(Collection& collection,size_t offset)
{
return FromNth< Collection>(collection,offset);
}
模板< typename Collection>
auto begin(const FromNth< Collection>&wrapper) - > decltype(wrapper.begin())
{
return wrapper.begin();
}
模板< typename Collection>
auto end(const FromNth< Collection>&wrapper) - > decltype(wrapper.end())
{
return wrapper.end();
}
int main()
{
std :: vector< int> (2),(3),(5),(7),(11),13,17,19,23 (auto x:makeFromNth(coll,1))
{
std :: cout<< x<< \\\
;
}
return 0;
$ b注意我的fromNthbegin是未定义的行为,如果输入的大小小于偏移量。 (如果它是相等的,那么它是很好的定义,并开始==结束)。请注意:如果您使用的是最新版本的boost,那么 iterator_range
可能会已经为您提供了一个类似于我的FromNth的收藏。 (auto const& s:boost :: make_iterator_range(v.begin()+ 1,v.end())
)
{
process(s);
$ / code>
注意:上面的代码在 decltype语句(在C ++ 11中需要模板)。
$ b 输出:
sh-4.3 $ g ++ -std = c ++ 11 -o main * .cpp
sh-4.3 $ main
3
5
7
11
13
17
19
23
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);
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)?
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)
解决方案 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 << '\n';
}
return 0;
}
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.
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 );
}
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).
Output:
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屋!