2013-07-05 27 views
6

Ho un std::map, che voglio ripetere durante l'avvio alla seconda voce.Perché non posso fare std :: map.begin() + 1?

Posso risolvere questo problema, ma sono confuso sul motivo per cui la sintassi "ovvia" non viene compilata. Il messaggio di errore non aiuta perché si riferisce a std::string, che non sto usando qui.

Ecco po 'di codice

// suppose I have some map ... 
std::map<int, int> pSomeMap; 

// this is fine ... 
std::map<int, int>::const_iterator pIterOne = pSomeMap.begin(); 
++pIterOne; 

// this doesn't compile ... 
std::map<int, int>::const_iterator pIterTwo = pSomeMap.begin() + 1; 

VS2012 dà il seguente errore sulla riga sopra

errore C2784: 'std :: _ String_iterator < _Mystr> std :: operator + (_ String_iterator < _Mystr> :: difference_type, std :: _ String_iterator < _Mystr>) ': impossibile dedurre argomento modello per' std :: _ String_iterator < _Mystr> 'da' int '

Qualcuno può spiegare cosa sta succedendo qui?

+1

Il messaggio di errore più bizzarro di sempre? – curiousguy

risposta

11

std::map<T>::iterator è di iteratore iteratore di classe iteratore. Questi hanno solo operatori ++ e --. +N e [] è disponibile solo per gli iteratori di accesso casuale (che può essere trovato ad esempio std::vector<T>).

La ragione di questo è che l'aggiunta di N ad un accesso casuale iteratore è costante di tempo (ad esempio aggiungi N*sizeof(T) ad un T*), mentre a fare la stessa cosa per un iteratore bidirezionale richiederebbe l'applicazione di ++N volte.

Cosa si può fare anche se (se si dispone di C++ 11) è:

std::map<int, int>::const_iterator pIterTwo = std::next(pSomeMap.begin(),1); 

che fa la cosa giusta per tutti i tipi di iteratori.

+2

È eccellente: anche 'std :: next' sembra molto più pulito. Grazie +1. –

+0

@RogerRowland Si noti che 'std :: next' è un'aggiunta di C++ 11. Ma se non hai C++ 11, è abbastanza facile implementare il tuo 'next' usando' std :: advance'. O usa 'boost :: next'. – juanchopanza

+0

@juanchopanza grazie, ho VS2012 che è probabilmente il più vicino che MS potrà mai ottenere in C++ 11! Compila e funziona bene. –

6

std::map gli iteratori sono bidirezionali, quindi forniscono solo ++ e - operatori, ma non operator+, anche se è +1.
È possibile utilizzare std::advance se è veramente necessario simulare l'operatore +, ma ciò si tradurrebbe in una sequenza di incremento chiamata per l'iteratore.

+1

Perché ha scelto di lamentarsi della stringa? – doctorlove

+0

Questo è utile, grazie, anche se come @doctorlove, non riesco ancora a capire l'errore del compilatore. Mi chiedo cosa riferiscono gli altri compilatori. –

+0

@doctorlove Beh, è ​​meglio chiedere agli sviluppatori del compilatore msvc. gcc offre tutte le possibili deduzioni. http://ideone.com/UUz5Xr – alexrider

Problemi correlati