Qualcuno può dirmi come incrementare l'iteratore di 2?Come incrementare un iteratore di 2?
iter++
disponibile - devo fare iter+2
? Come posso raggiungere questo obiettivo?
Qualcuno può dirmi come incrementare l'iteratore di 2?Come incrementare un iteratore di 2?
iter++
disponibile - devo fare iter+2
? Come posso raggiungere questo obiettivo?
è possibile utilizzare il 'assegnazione con l'aggiunta' operatore
iter += 2;
Mi chiedevo se ++ iter ++ avrebbe funzionato, ma penso che sarebbe solo confuso. – Xetius
Cosa succederà se l'iteratore punta attualmente sull'ultimo elemento? Dove indicherà dopo l'incremento? – sharptooth
@Xetius: non dovresti farlo. È un comportamento indefinito. – Naveen
Questo metodo funziona per iteratori che non sono iteratori ad accesso casuale, ma può ancora essere specializzate per l'attuazione di essere non meno efficiente di iter += 2
quando utilizzato con iteratori ad accesso casuale.
Cosa succederà se l'iteratore punta attualmente sull'ultimo elemento? Dove indicherà dopo l'incremento? Ho provato con VC++ - solo avanzamenti e confronti con vector :: end() restituisce false dopo. Questo è il modo giusto per comportamento indefinito, suppongo. – sharptooth
Sì, se stai andando a fare std :: advance con '2' o + = 2 o due '++' senza cercare 'end' nel mezzo, allora hai bisogno di una garanzia esterna che sei non andando ad andare oltre il passato. (Ad esempio, potresti * sapere * che stai iterando attraverso gli elementi pari (su base zero) di una raccolta che è garantita per avere un numero pari di elementi.) –
qual è la differenza tra next (iter, 2) e next (iter, 2) – m1350
http://www.cplusplus.com/reference/std/iterator/advance/
std::advance(it,n);
dove n è 2 nel tuo caso.
La bellezza di questa funzione è che, se "si" è un iteratore ad accesso casuale, il digiuno
it += n
operazione viene utilizzata (cioè vettore < ,,> :: iterator). In caso contrario, la sua resa al
for(int i = 0; i < n; i++)
++it;
(vale a dire l'elenco < ..> :: iterator)
La risposta molto semplice:
++++iter
La risposta lunga:
è davvero dovrebbe ottenere utilizzato per scrivere ++iter
anziché iter++
. Quest'ultimo deve restituire (una copia di) il vecchio valore, che è diverso dal nuovo valore; questo richiede tempo e spazio.
Nota che l'incremento del prefisso (++iter
) prende un valore e restituisce un valore, mentre l'incremento postfisso (iter++
) prende un valore e restituisce un valore.
Comportamento non definito se 'iter' è un puntatore raw (che possono essere alcuni tipi di iteratore). '++ esso; ++ it; "andrebbe bene. –
Cattiva idea e non è molto leggibile. –
Per favore dimmi che questa non è una risposta seria. – Axle
Se non si sa se si hanno abbastanza elementi successivi nel contenitore o no, è necessario verificare la fine del contenitore tra ogni incremento. Né ++ né std :: advance lo faranno per te.
if(++iter == collection.end())
... // stop
if(++iter == collection.end())
... // stop
È anche possibile eseguire il rollover della propria funzione di avanzamento sicuro.
Se sei sicuro di non andare oltre la fine, allora std :: advance (iter, 2) è la soluzione migliore.
Se non si dispone di un lvalue modificabile di un iteratore, o si desidera ottenere una copia di un dato iteratore (lasciando l'originale invariato), quindi C++ 11 viene fornito con nuove funzioni di supporto - std::next
/std::prev
:
std::next(iter, 2); // returns a copy of iter incremented by 2
std::next(std::begin(v), 2); // returns a copy of begin(v) incremented by 2
std::prev(iter, 2); // returns a copy of iter decremented by 2
Se ho un iteratore come questo: 'map
@HaniGoc Solo it_tmp – metamorphosis
possiamo usare sia anticipo così come accanto. Ma c'è una differenza tra i due. "advance" modifica il suo argomento e non restituisce nulla.Così, può essere utilizzato come:
vector<int> v;
v.push_back(1);
v.push_back(2);
auto itr = v.begin();
advance(itr, 1); //modifies the itr
cout << *itr<<endl //prints 2
"next" restituisce una copia modificata del iteratore
vector<int> v;
v.push_back(1);
v.push_back(2);
cout << *next(v.begin(), 1) << endl; //prints 2
Supponendo dimensione elenco non sia un multiplo pari passo è necessario evitare overflow:
static constexpr auto step = 2;
// Guard against invalid initial iterator.
if (!list.empty())
{
for (auto it = list.begin(); /*nothing here*/; std::advance(it, step))
{
// do stuff...
// Guard against advance past end of iterator.
if (std::distance(it, list.end()) > step)
break;
}
}
A seconda dell'implementazione della raccolta, il calcolo della distanza può essere molto lento. Di seguito è ottimale e più leggibile. La chiusura potrebbe essere cambiato a un modello di servizio con il valore della lista end passato per riferimento const:
const auto advance = [&](list_type::iterator& it, size_t step)
{
for (size_t i = 0; it != list.end() && i < step; std::next(it), ++i);
};
static constexpr auto step = 2;
for (auto it = list.begin(); it != list.end(); advance(it, step))
{
// do stuff...
}
Se non c'è loop:
static constexpr auto step = 2;
auto it = list.begin();
if (step <= list.size())
{
std::advance(it, step);
}
A giudicare dalla gamma di risposte, potrebbe essere necessario chiarire la tua domanda. – teabot
Sì. Che tipo di iteratore è? Mostra un po 'di codice. –