Вопрос
У меня есть цикл, который читает каждую строку в файле, используя getline()
:
istream is;
string line;
while (!getline(is, line).eof())
{
// ...
}
Я заметил, что звоню getline()
вроде это тоже работает:
while (getline(is, line))
Что тут происходит? getline()
возвращает ссылку на поток.Он каким-то образом преобразуется в указатель?Действительно ли это хорошая практика или мне следует придерживаться первой формы?
Решение
В istream
, возвращаемом getline ()
, неявно вызывается метод оператора void * ()
, который возвращает информацию о том, был ли запущен поток в ошибку. Таким образом, он делает больше проверок, чем вызов eof ()
.
Другие советы
Обновлено:
Я ошибочно указал на документация Basic_istream для метода оператора bool() в классе Basic_istream::sentry, но, как уже отмечалось, на самом деле это не то, что происходит.Я проголосовал за правильные ответы Чарльза и Люка.На самом деле вызывается оператор void*().Подробнее об этом в FAQ по C++.
Чарльз дал правильный ответ.
То, что называется, действительно std::basic_ios::operator void*()
, и не sentry::operator bool()
, что согласуется с тем, что std::getline()
возвращает std::basic_istream
(таким образом, std::basic_ios
), а не часовой.
Для неверующих см.:
- std::basic_ios::operator void*() документация на сайте cppreference,
- А Идиома Safe Bool статья об артиме,
- Часто задаваемые вопросы по C++ Lite §15.4,
- стандарт, ...
В противном случае, как уже говорили другие, предпочтите вторую форму, которая является канонической.Не используйте fail()
если вам действительно нужен подробный код - я никогда не помню, нужен ли xxx.good()
можно использовать вместо !xxx.fail()
Я бы придерживался первой формы. Хотя вторая форма может работать, она вряд ли является явной. Ваш исходный код четко описывает, что делается и как он будет себя вести.