Domanda
Ho un ciclo che legge ogni riga di un file usando getline ()
:
istream is;
string line;
while (!getline(is, line).eof())
{
// ...
}
Ho notato che anche chiamare getline ()
in questo modo sembra funzionare:
while (getline(is, line))
Cosa sta succedendo qui? getline ()
restituisce un riferimento di flusso. Viene in qualche modo convertito in un puntatore? È davvero una buona pratica o dovrei attenermi alla prima forma?
Soluzione
istream
restituito da getline ()
sta facendo chiamare implicitamente il suo operatore void * ()
, che restituisce se lo stream è stato eseguito in un errore. Come tale, sta effettuando più controlli di una chiamata a eof ()
.
Altri suggerimenti
Aggiornamento:
Avevo erroneamente indicato documentazione basic_istream per il metodo operator bool () sulla classe basic_istream :: sentry, ma come è stato sottolineato questo non è realmente ciò che sta accadendo. Ho votato le risposte corrette di Charles e Luc. In realtà è l'operatore void * () che viene chiamato. Maggiori informazioni su questo nelle Domande frequenti su C ++ .
Charles ha dato la risposta corretta .
Ciò che viene chiamato è in effetti std :: basic_ios :: operator void * ()
, e non sentry :: operator bool ()
, che è coerente con il fatto che std :: getline ()
restituisce un std :: basic_istream
(quindi, un std :: basic_ios
), e non una sentinella.
Per i non credenti, vedi:
- std :: basic_ios :: operator void * () documentazione sul sito cppreference,
- L'articolo The Safe Bool Idiom su artima ,
- FAQ C ++ lite & # 167; 15.4 ,
- lo standard, ...
Altrimenti, come altri hanno già detto, preferiscono la seconda forma che è canonica. Non usare fail ()
se davvero vuoi un codice dettagliato - Non ricordo mai se xxx.good ()
può essere usato al posto di ! Xxx.fail ( )
Continuerei con la prima forma. Mentre il secondo modulo può funzionare, è poco esplicito. Il codice originale descrive chiaramente cosa viene fatto e come dovrebbe comportarsi.