2009-05-10 14 views
9

Mi chiedevo, come viene stabilita l'uguaglianza (==) per gli iteratori STL? E 'un semplice confronto tra puntatori (e quindi basato su indirizzi) o qualcosa di più elaborato?Come viene stabilita l'uguaglianza dell'iteratore STL?

Se ho due iteratori da due diversi elenchi di oggetti e li confronto, il risultato sarà sempre falso?

Che dire se confronto un valore valido con uno fuori gamma? È sempre falso?

risposta

11

Le classi di Iterator possono definire operatori == sovraccarichi, se lo desiderano. Quindi il risultato dipende dall'implementazione di operator==.

In realtà non si dovrebbe confrontare gli iteratori da diversi contenitori. Penso che alcune implementazioni di debug STL segnaleranno un avvertimento se lo fai, il che ti aiuterà a individuare casi di questo uso errato nel tuo codice.

+6

Non dovrebbe? Certamente non devi assolutamente! – xtofl

+0

La possibilità di confrontare tecnicamente gli iteratori da diversi contenitori rende MSVC un fastidioso avviso di deprecazione quando si utilizza 'std :: copy' ... –

2

Mi chiedevo, come viene stabilita l'uguaglianza (==) per gli iteratori STL?

Non tutti gli iteratori possono essere confrontati (ad esempio, gli Iteratori di output non sono necessari per fornire op==). È possibile utilizzare operator== quando il concetto di intervallo è ben definito per la categoria di iteratore in esame.

E 'un semplice confronto tra puntatori (e quindi basato su indirizzi) o qualcosa di più elaborato?

Gli iteratori sono sempre implementati con puntatori. Edit: Dico implementato con - che si riferisce non a un requisito standard ma piuttosto alla pratica di usare i poitner come costrutto sottostante. Implementazioni (come VS) possono però avere controlli di convalida speciali inseriti.

Se ho due iteratori da due diversi elenchi di oggetti e li confronto, il risultato sarà sempre falso?

Si sta invocando il comportamento non definito.

Che dire se confronto un valore valido con uno fuori gamma? È sempre falso?

Di nuovo, invocherete UB. L'unico confronto valido è tra due iteratori nello stesso intervallo o tra uno nell'intervallo e un altro dopo l'ultimo. Nota, puoi solo confrontare l'iteratore con uno-passato l'ultimo elemento, dereferendo gli stessi lead a UB.

+4

" Gli iteratori sono sempre implementati come puntatori ". Non penso che insert_iterator sia un semplice puntatore.Mi aspetterei che sia un oggetto contenente un puntatore o un riferimento a un contenitore, oltre a un iteratore su quel contenitore. –

+0

Do un'occhiata. Le implementazioni che ho visto usano un puntatore al contenitore. – dirkgently

+2

Solo lo std :: vector :: iterator è garantito per essere convertibile in un puntatore. Molti probabilmente indicano _use_ ai loro nodi. Alcuni usano due indicatori. Alcuni potrebbero usare un puntatore di file. Puoi quindi affermare che sono implementati come puntatori? Io non la penso così Non oserei basare alcun progetto su questo. – xtofl

1

Il test di uguaglianza è specifico per il tipo di iteratore in uso o potrebbe non esistere affatto. Se vuoi davvero sapere, puoi sempre controllare il codice sorgente dell'implementazione di STL che stai utilizzando, cercare l'operatore ==() nella classe iteratore.

Gli iteratori NON sono sempre puntatori, e in effetti in alcune versioni "sicure" dell'STL, non sono mai indicatori. Gli iteratori per i vettori e le stringhe sono comunemente implementati come indicatori perché possono esserlo. Iterator per deques, liste, insiemi e mappe non possono essere puntatori in un'implementazione semi efficiente.

Quali iteratori sono un tipo di puntatore intelligente. Seguono il principio generico secondo cui se guardano e si comportano come un puntatore, allora sono un puntatore per quanto riguarda l'utente.

3

Daniel ha chiesto: Mi chiedevo, come sta uguaglianza (==) stabilito per iteratori STL? È un semplice confronto tra puntatori (e quindi basato su indirizzi) o qualcosa di più stravagante?

Dipende dall'implementazione. In questo momento, su Visual C++ 2008, vedo il seguente codice (per l'elenco iteratore):

bool operator==(const _Myt_iter& _Right) const 
{ // test for iterator equality 

#if _HAS_ITERATOR_DEBUGGING 
    _Compat(_Right); 
#else 
    _SCL_SECURE_TRAITS_VALIDATE(this->_Has_container() && this->_Same_container(_Right)); 
#endif /* _HAS_ITERATOR_DEBUGGING */ 

    return (_Ptr == _Right._Ptr); 
} 

Vedrai sopra che v'è sia il codice per la verifica di validità iteratore, e _Ptr essere un puntatore ad una lista nodo

Quindi immagino ci sia sia la verifica, sia il semplice confronto dei puntatori grezzi.

Daniel ha chiesto: Se ho due iteratori da due diversi oggetti lista e li metto a confronto, sarà il risultato sarà sempre falso?

Fino ad ora, sembra che lo standard non fosse chiaro sull'argomento. A quanto pare, saranno esplicitamente scrivere che questo tipo di operazione è indefinito risultati:

Citando: http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#446

Il risultato dell'utilizzo di qualsiasi operazione iteratore (24.2.1 [input.iterators], 24.2.2 [output.iterators], 24.2.3 [forward.iterators], 24.2.4 [bidirectional.iterators], 24.2.5 [random.access.iterators]) che utilizza due valori iteratori come argomenti (nota in calce) che erano ottenuto da due diversi intervalli r1 e r2 (compresi i loro valori passati) che non sono intervalli secondari di un intervallo comune non è definito, se non diversamente specificato.

nota) Tra gli altri queste operazioni sono ==, <, binario - e copiare l'assegnazione

Quindi credo che sia male per confrontare iteratore da contenitori diversi ... ^ _^

Daniel ha chiesto: E se confrontassi un valore valido con uno fuori gamma? È sempre falso?

Come sopra.