【问题标题】:Using auto (for iterating) in nested range-based for loop在基于范围的嵌套 for 循环中使用自动(用于迭代)
【发布时间】:2015-10-25 18:38:01
【问题描述】:

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

如果我需要遍历vector,我会这样做:

vector<int>v; 

for(auto it : v){    

   cout << it <<endl; 

}

但是假设我需要做类似的事情:

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

   }    
}

我完全不知道该怎么做。请建议什么是合适的方法。提前谢谢。

【问题讨论】:

  • 目前还不清楚您期望发生什么。你能举一个(完整!)的例子吗?

标签: c++ c++11 vector iterator auto


【解决方案1】:

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

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

这里有一个简单的例子让你开始(注意使用auto&amp;而不是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;
    }
}

输出:

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: 

编辑:如果您定义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 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;
}

【讨论】:

  • 哇,真的很简单,很有表现力
【解决方案2】:
auto it:v

是...的简写

auto it = v.begin(); it != v.end(); it++

所以要在嵌套的 for 循环中使用 auto,较长的版本更合适...

#include <iostream>
#include <vector>

using namespace std;

int main()
{
    vector<int> v(10, 17);
    for (auto& it = v.begin(); it != v.end(); ++it) {
        for (auto& it2 = it + 1; it2 != v.end(); ++it2) {
            cout << *it2 << " ";
        }
        cout << endl;
    }

    // system("pause");
    return 0;
}

【讨论】:

  • 您确定这将使用auto&amp; 而不是auto 编译吗?
  • 大概就是这个原因。
  • 我不认为这应该是投反对票的理由。我的回答不是“是的,我确定”。我的回答是“在我的 IDE 中它编译为两者”。然后我编辑了我的代码。所以不仅否决票不公平,而且它也可以被删除,对吧?
  • 牛排就好了!
  • 说“plz”,你可能会得到一个。
猜你喜欢
  • 1970-01-01
  • 2017-03-20
  • 1970-01-01
  • 2011-10-20
  • 1970-01-01
  • 2014-09-13
  • 2022-01-14
  • 2016-10-31
  • 2016-04-03
相关资源
最近更新 更多