2013-02-25 15 views
5

Ho scritto una classe che si comporta come un iteratore per analizzare file in formato CSV. Ho anche scritto altre classi per leggere file csv specifici per riempire direttamente una struttura MyObject. Così la classe può essere utilizzata come quello (ho rimosso la movimentazione parte del codice di errore):è una buona cosa usare gli iteratori per leggere su un flusso formattato?

std::ifstream in(filename); 
MyObjectParser parser(in); 
MyObjectParser::Iterator it; 
for (it = parser.begin(); it != parser.end(); it++) 
{ 
    MyObject b = *it; 
    // do some stuff here ... 
} 

Il programma funziona bene e sono felice con lui, ma mi sono reso conto che il significato implicito (solo per me?) di un iteratore è che iterà su una collezione. In questo caso non esiste una raccolta ma un flusso.

Devo preferire una forma che suggerisco esplicitamente sto usando un flusso da sovraccarico operatore >> e avendo così qualcosa di simile:

std::ifstream in(filename); 
MyObjectReader reader(in); 
MyObject obj; 
while(reader >> obj) 
{ 
    // do the same "some stuff" here... 
} 

E 'solo una questione di gusto? Non vedo chiaramente quali sono le differenze (eccetto che nella seconda forma l'oggetto è appena riempito e non copiato) e quali sono le conseguenze della scelta della prima o della seconda forma.

Sarei felice di avere altre opinioni per sapere esattamente perché sto usando una soluzione piuttosto che un'altra.

+0

Chi dice che gli iteratori dovrebbero scorrere le * collezioni *? La mia comprensione è che gli iteratori iterano su * qualcosa *, * qualcosa * essendo ** qualsiasi tipo di dati **, ad esempio un contenitore, un flusso (file, dati di rete, ...) o anche alcuni impliciti (forse fittizi) dati. Mantieni generale. ;) Personalmente mi piace la tua interfaccia basata su iteratore. – leemes

risposta

6

È possibile considerare uno stream come una raccolta se lo si desidera.

avrei notare, tuttavia, che da sovraccarico operator>>, si possono avere entrambe le cose - si può leggere in modo esplicito i dati dal flusso utilizzando operator>> direttamente, o è possibile trattare il flusso come una raccolta utilizzando std::istream_iterator<whatever> per trattare è come una collezione.

Stando così le cose, mi sembra che l'overloading operator>> sia la scelta più ovvia, poiché da quel momento è possibile trattare le cose in entrambi i modi essenzialmente senza lavoro extra. Inoltre, l'utilizzo di std::istream_iterator<x> è un linguaggio abbastanza riconoscibile, poiché è incluso nella libreria standard.

2

Il concetto di iterazione non dipende da quello dei contenitori. Iteratori iterano su una sequenza di valori. Diverse configurazioni di iteratore definiscono la sequenza in modi diversi, ma c'è sempre idee del valore corrente, avanzano e raggiungono la fine. L'unico problema con gli iteratori di input è che solo terminano alla fine del file; per esempio, non è possibile dire che le 10 righe successive contengono il doppio, e quindi passiamo a qualcos'altro. (Ma ovviamente, puoi inserire un filtro streambuf nello stream per rilevare la fine.)

Problemi correlati