Newsgroup: it.comp.lang.c++
Titolo: iteratori stl

ciao
Volevo sapere se e' ok salvare la posizione di un iteratore ad un
std::vector. In pratica, vorrei sapere se e' garantito che punti sempre allo
stesso elemento o no.
Ovviamente assumo che il vettore abbia una dimensione iniziale sufficiente a
contenere tutti gli  elementi, e che io chiami solo push_back per inserire
gli elementi.
E per std::deque?
Ciao e grazie
Alex

 ha scritto nel messaggio
news:3cbd512d$0$234$cc9e...@news.dial.pipex.com...

Inserire elementi con push_back può portare a riempire completamente lo
spazio dell' array allocato dal vector.
A questo punto avviene una riallocazione e quindi i dati potranno essere
copiati in un array più grande che non avrà lo stesso indirizzo del
precedente.
L' iteratore dei vector è, per ragioni di efficenza,  di solito un puntatore
e quindi puoi immaginare cosa può succedere.
In generale per i vector gli iteratori rimangono validi finchè un elemento
intermedio non viene inserito o rimosso (l' espansione o l' impaccamento
farebbero puntare ad un elemento diverso) o non avviene appunto una
riallocazione per variare la capacità del vector.
Se quindi lo spazio allocato all' inizio è sufficiente e non vengono
inseriti o rimossi elementi intermedi si può fare.
Problemi maggiori per std::deque dove qualsiasi operazione di inserimento o
eliminazione invalida gli iteratori.
----
Sergio Bianchi

 wrote in message
news:f6dv8.47776$SR5.1...@twister1.libero.it...


 inserire gli elementi.
a questo punto entrano in gioco i metodi size() e capacity().
size() restituisce il numero di oggetti in uso nel vettore
capacity() restituisce il numero di oggetti allocati correntemente.
Lo standard garantisce che se abbiamo un std::vector<> v e abbiamo
        v.capacity() > v.size()
allora una successiva chiamata a v.push_back() non invalidera` alcun 
iteratore.
Quindi per essere sicuro di non invalidare gli iteratori devi allocare 
abbastanza spazio con il metodo reserve(). Ad esempio:
std::vector<int> v;
v.reserve(2); // alloca memoria per almeno due elementi
v.push_back(4); // ok
v.push_back(7); // ok
v.push_back(3); // warning: gli iteratori precedenti potrebbero 
        //non essere piu` validi
Nota infine che la chiamata a reserve() *non* equivale a inizializzare 
un vector con un parametro di tipo intero:
        std::vector<int> v(10);
e` diverso da
        std::vector<int> v;
        v.reserve(10);
Nel primo caso allochi memoria per 10 interi e li costruisci: quindi 
v.size()==10. Nel secondo caso allochi solo la memoria senza costruire 
alcunche`, quindi v.size()==0.
ciao Anto
-- 
Antonio Cuni, 19 anni, studente
Brainbench C++ Master: 4.73, higher than 99% of all previous test takers.
C Language: 3.79, higher than 92% of all previous test takers.
Guida C/C++ di Programmazione.it: 
http://cpp.programmazione.it

 wrote in message
news:a9kes1$8ft$4...@newsreader.mailgate.org...


 }
Qualche appunto.  Per cominciare, non controlli se l'apertura del file
e' andata a buon fine.  Inoltre, leggi in una string che poi viene
copiata su un'altra; perche'?  Non conviene leggere nella string
finale direttamente?  Poi: la string viene creata vuota e, se il file
e' di una certa dimensione, verra' espansa (e quindi riallocata) piu'
volte, con conseguente perdita di tempo; non conviene settarla
opportunamente fin dall'inizio?  Infine (last but not least); la
maniera di riempire la string non mi piace :-)
Io farei cosi' (non testato, chissa' quanti errori ;-)
std::ifstream inputFile(fileName);
if (inputFile) {
  inputFile.seekg(0, std::ios::end);
  std::ifstream::pos_type p = inputFile.tellg();
  std::cout << "Il mio file e' lungo " << p << " bytes" << std::endl;
  inputFile.seekg(0);           // Mi riposiziono all'inizio
  str.reserve(p);               //   e chiedo abbastanza spazio
                                //     nella mia string
  std::copy(std::istreambuf_iterator<char>(inputFile),
            std::istreambuf_iterator<char>(),
            std::back_inserter(str));
  inputFile.close();            // E' buona educazione chiudere quello
                                //   che si e' aperto
  std::cout << "Il file contiene: =====>" << str << "<=====\n";
} else {
  std::cerr << "Aiuto!  Non riesco ad aprire " << fileName << std::endl;
}
-- 
Maurizio Loreti                         
http://www.pd.infn.it/~loreti/mlo.html
Dept. of Physics, Univ. of Padova, Italy          loreti at pd dot infn dot it

 quello che hai detto per vector e' vero anche per deque?
tratto direttamente dalla STL Reference di SGI:
[3] The semantics of iterator invalidation for deque is as follows. 
Insert (including push_front and push_back) invalidates all iterators 
that refer to a deque. Erase in the middle of a deque invalidates all 
iterators that refer to the deque. Erase at the beginning or end of a 
deque (including pop_front and pop_back) invalidates an iterator only if 
it points to the erased element. 
