Pergunta
Eu tenho um loop que lê cada linha em um arquivo usando getline()
:
istream is;
string line;
while (!getline(is, line).eof())
{
// ...
}
notei que getline()
chamando assim também parece funcionar:
while (getline(is, line))
O que está acontecendo aqui? getline()
retorna uma referência corrente. Está sendo convertido para um ponteiro de alguma forma? É este, na verdade, uma boa prática ou devo ficar com a primeira forma?
Solução
O istream
retornado por getline()
está tendo seu método void*()
operador chamado implicitamente, que retorna se o fluxo foi executado em um erro. Como tal, ele está fazendo mais verificações do que uma chamada para eof()
.
Outras dicas
Atualizado:
Eu tinha erradamente apontou para o basic_istream documentação para o método bool operator () na classe basic_istream :: sentinela, mas como já foi assinalado este não é realmente o que está acontecendo. Eu votei-se de Charles e Luc respostas corretas. É realmente operador * void () que está sendo chamado. Mais sobre isso no C ++ FAQ .
Charles deu a resposta correta .
O que é chamado é realmente std::basic_ios::operator void*()
, e não sentry::operator bool()
, o que é consistente com o fato de que std::getline()
retorna um std::basic_istream
(assim, um std::basic_ios
), e não uma sentinela.
Para os não crentes, consulte:
- std :: basic_ios :: operator vazio * () documentação no local cppreference,
- The Safe Bool Idiom artigo em Artima ,
- C ++ FAQ Lite §15.4 ,
- o padrão, ...
Caso contrário, como outros já disse, prefiro a segunda forma que é canônica. Usar não fail()
se realmente você quer um detalhado código - Eu nunca me lembro se xxx.good()
pode ser usado em vez de !xxx.fail()
Gostaria de ficar com a primeira forma. Enquanto a segunda forma pode funcionar, é pouco explícita. Seu código original descreve claramente o que está sendo feito e como é esperado para se comportar.