2015-10-25 14 views
5

Attualmente ho iniziato a utilizzare auto keyword.I avere qualche dubbio in merito che:Utilizzando automatico (per iterazione) in nested gamma basata su ciclo for

Se ho bisogno di attraversare il vector che faccio:

vector<int>v; 

for(auto it : v){  

    cout << it <<endl; 

} 

Ma supponiamo che se ho bisogno di fare qualcosa di simile:

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 

    }  
} 

non ho assolutamente idea di come fare that.Please suggerire che cosa è il metodo appropriato per tale .Grazie in anticipo.

+1

E 'davvero chiaro cosa ci si aspetta di accadere. Puoi dare un esempio * buono * (completo!)? –

risposta

3

Presumo che si voglia utilizzare autoe il nuovo ciclo basato su intervallo for.

È possibile creare un vector_view e iterare sul "vettore secondario" nel ciclo interno.

Ecco un semplice esempio per iniziare (notare l'uso di auto& e non 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; 
    } 
} 

uscita:

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: 

EDIT: Puoi fare la sincronizzazione ax meno prolissa se si definisce una funzione 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_}; 
} 

E grazie al tipo di modello argomento detrazione, è possibile scrivere:

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

Wow yeah davvero semplice ed espressivo –

2
auto it:v 

è una scorciatoia per. ..

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

in modo da usare auto all'interno cicli for innestati, la versione più lunga è più appropriato ...

#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; 
} 
+0

Sei sicuro che questo verrà compilato con 'auto &' e non 'auto'? –

+0

In VS 2015 Community Edition viene compilato come entrambi. – dspfnder

+0

A causa di estensioni specifiche della compilazione: http://ideone.com/D5ZlTq –