Я проверил стандарт C ++ 11 и обнаружил следующие факты:
std::getline(fin, str)
возвращает basic_ios
объект, чей класс имеет функцию-член explicit operator bool() const;
Класс basic_ios
не имеет функции-члена operator void*() const;
как pre-C ++ 11.
Я так думаю if (getline(fin, str)) {}
не соответствует стандартам Это должно быть написано как
if (bool(getline(fin, str)){}
, (Тем не менее, VC ++ 2012 выдает предупреждение об этом использовании. То есть заставляет void * to bool)
Я прав?
Дэвид прав, и вот цитаты, чтобы поддержать его. В §12.3.2 / 2 Стандарт гласит:
Функция преобразования может быть явной (7.1.2), и в этом случае она рассматривается только как
пользовательское преобразование для прямой инициализации (8.5). В противном случае пользовательские преобразования
не ограничены для использования в назначениях и инициализациях. [ пример:class Y { }; struct Z { explicit operator Y() const; }; void h(Z z) { Y y1(z); // OK: direct-initialization Y y2 = z; // ill-formed: copy-initialization Y y3 = (Y)z; // OK: cast notation }
— конец примера]
Некоторые места, где происходит это контекстное преобразование, находятся в операнде !
Операнды &&
и состояние if
,
Так прямая инициализация может использовать явные операторы преобразования, и в § 4/3,
Выражение e может быть неявно преобразовано в тип
T
если и только если
декларацияT t=e;
хорошо сформирован, для некоторых изобрел временный
переменная t (8,5). Определенные языковые конструкции требуют, чтобы
выражение должно быть преобразовано в логическое значение. Выражение e появляется
в таком контексте, как говорят, контекстно преобразуется в bool и является
правильно сформированный, если и только если декларацияbool t(e);
хорошо сформирован,
для какой-то придуманной временной переменнойt
(8,5) …
Итак, как вы можете видеть, стандарт определяет прямую инициализацию для контекстных преобразований «как будто», поэтому явные преобразования работают в if
условия.
Код соответствует. Оператор явного преобразования в bool
будет вызываться, когда объект используется как состояние автоматически. Изменение в стандарте должно было сохранить то же самое использование, делая его немного более безопасным.
explicit operator bool
(а также только explicit operator bool
) имеет специальный язык, который позволяет неявно преобразовывать его в bool
в определенный обстоятельства. Язык спецификации для этого преобразования «контекстно преобразуется в bool
».
Это места, где язык выполняет булево тестирование. Условное выражение, используемое if/while/for
«контекстно преобразуется в bool
«. Как логические операторы и условный оператор (?:
).
Итак, пока вы не можете сделать это:
bool b = std::getline(fin, str);
void func(bool) {}
func(std::getline(fin, str));
Вы можете сделать это:
while(std::getline(fin, str)) {...}
for(;std::getline(fin, str);) {...}
if(std::getline(fin, str) && somethingElse) {...}