在嵌套的基于范围的for循环中使用auto(用于迭代)

bha*_*anu 5 c++ iterator vector auto c++11

目前我已经开始使用auto关键字.我对此有一些疑问:

如果我需要遍历vector我:

vector<int>v; 

for(auto it : v){    

   cout << it <<endl; 

}
Run Code Online (Sandbox Code Playgroud)

但是假设我需要做以下事情:

vector<int>v;

for(auto it:v){    
   for(auto jt:X){

   //where X is next position of it's position
   //What I mean is if it is currently at 2nd position then 
   //jt iterator will start from 3rd position

   }    
}
Run Code Online (Sandbox Code Playgroud)

我完全不知道该怎么做.请建议适当的方法.提前谢谢.

mad*_*uri 3

我假设您想要使用auto 的基于范围的for循环。

您可以创建一个vector_view并迭代内部循环中的“子向量”。

这是一个帮助您入门的简单示例(请注意使用auto&和 not auto):

Run It Online

#include <iostream>
#include <cstddef>
#include <numeric>
#include <vector>
using std::cout;
using std::endl;

template <typename T, typename A>
struct vector_view
{
    using vector_type    = std::vector<T, A>;
    using const_iterator = typename vector_type::const_iterator;
    using       iterator = typename vector_type::iterator;

    vector_type& vec;
    size_t       _begin;
    size_t       _length;

    vector_view(vector_type& v, size_t begin_, size_t length_)
    : vec(v), _begin(begin_), _length(length_) {}

    const_iterator begin() const { return vec.begin() + _begin; }
    iterator       begin()       { return vec.begin() + _begin; }

    const_iterator end()   const { return vec.begin() + _begin + _length; }
    iterator       end()         { return vec.begin() + _begin + _length; }
};

int main()
{
    std::vector<int> v(10);
    std::iota(v.begin(), v.end(), 0);

    for (auto& it : v)
    {
        size_t begin  = std::distance(&v[0], &it) + 1;
        size_t length = v.size() - begin;
        vector_view<typename decltype(v)::value_type,
                    typename decltype(v)::allocator_type
        > vv(v, begin, length);

        cout << it << ": ";
        for (auto& jt : vv)
        {
            cout << jt << " ";
        }
        cout << endl;
    }
}
Run Code Online (Sandbox Code Playgroud)

输出:

0: 1 2 3 4 5 6 7 8 9 
1: 2 3 4 5 6 7 8 9 
2: 3 4 5 6 7 8 9 
3: 4 5 6 7 8 9 
4: 5 6 7 8 9 
5: 6 7 8 9 
6: 7 8 9 
7: 8 9 
8: 9 
9: 
Run Code Online (Sandbox Code Playgroud)

编辑:如果定义一个函数,则可以使语法不那么冗长make_vector_view()

template <typename T, typename A>
vector_view<T, A> make_vector_view(std::vector<T, A>& v,
                                   size_t             begin_,
                                   size_t             length_)
{
    return {v, begin_, length_};
}
Run Code Online (Sandbox Code Playgroud)

并且由于模板参数类型推导,您可以编写:

Run It Online

for (auto& it : v)
{
    size_t begin  = std::distance(&v[0], &it) + 1;
    size_t length = v.size() - begin;

    cout << it << ": ";
    for (auto& jt : make_vector_view(v, begin, length))
    {
        cout << jt << " ";
    }
    cout << endl;
}
Run Code Online (Sandbox Code Playgroud)

  • 哇,是的,非常简单且富有表现力 (2认同)