C++ 11:来自第二个元素的范围循环向量?

pep*_*epr 6 for-loop stdvector c++11

我有std::vector<std::string> v;(初始化).如何使用range-for循环访问除第一个元素之外的所有元素(在索引0上).对于所有元素:

for (const string & s: v)
    process(s);
Run Code Online (Sandbox Code Playgroud)

代替的v范围的表达可以使用.如何编写范围表达式以跳过第一个元素(或跳过前n个元素)

我知道如何使用v.begin() + 1和使用经典循环来获得效果.我正在寻找新的,更具可读性的推荐替代方案.可能类似于Python切片的东西?...喜欢:

for s in v[1:]:
    process(s)
Run Code Online (Sandbox Code Playgroud)

Cas*_*Cow 6

创建一个包装器,其begin()和end()返回正确的迭代器,然后您可以将其用作第二个参数.

#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;
}
Run Code Online (Sandbox Code Playgroud)

请注意,如果输入的大小小于偏移量,则fromNth"begin"是未定义的行为.(如果它相等那么它的定义很好并且开始==结束).因此,请先进行尺寸检查.

注意:如果您使用的是最新版本的boost,那么iterator_range可能已经为您提供了类似于我的"FromNth"的"集合".

for( auto const& s : boost::make_iterator_range( v.begin() + 1, v.end() ) )
{
    process( s );
}
Run Code Online (Sandbox Code Playgroud)

注意:上面的代码使用C++ 11 GNU 4.8.3 在CodingGround上工作.(那个网站虽然很慢).从C++ 14开始,您将不需要 - > decltype语句(C++ 11中需要模板).

输出:

sh-4.3$ g++ -std=c++11 -o main *.cpp
sh-4.3$ main
3
5
7
11
13
17
19
23 
Run Code Online (Sandbox Code Playgroud)


Que*_*tin 5

直到范围进入标准库,你才会比普通C++中的vanilla更好!

for(auto i = begin(v) + 1, e = end(v); i !=e; ++i)
    // Do something with *i
Run Code Online (Sandbox Code Playgroud)

  • @CashCow 因为问题是关于将范围弯曲成形状,我假设是普通的 C++。我已经看到足够多的 Boost 知道如果你向它扔足够多的模板,*没有*是不可能的;) (2认同)
  • @pepr 当 C++ 有范围时我会回来的。\*邪恶的笑\* (2认同)