Подтвердить что ты не робот

Изменение поведения istream в С++ при сбое

Возьмите из: cppreference

До С++ 11:

Если извлечение завершится неудачно (например, если была введена буква, в которой ожидается цифра), значение остается неизмененным и устанавливается битбит.

Так как С++ 11:

Если извлечение завершилось неудачно, нуль записывается в значение и устанавливается failbit. Если извлечения приводит к слишком большому или слишком маленькому значению, чтобы соответствовать значению, записывается std::numeric_limits<T>::max() или std::numeric_limits<T>::min(), и устанавливается флаг сбоя.

Из-за этого изменения это означает, что следующий фрагмент:

int x = 1;
std::cin >> x;
return x;

если числовое преобразование не выполнено, вернет 1 до С++ 11 и 0 в противном случае.

Почему стандартный комитет внесет такое незначительное изменение? Вернее, какой код был возможен до С++ 11, который гарантировал это изменение?

4b9b3361

Ответ 1

Кажется, что изначально было указано, что operator>> были сломаны в некоторых случаях (т.е. строго говоря, не существовало). Это "исправление".

В проекте с начала 2011 года Стандарт в основном такой же, как и в 2003 году. Однако в отчете об ошибках библиотеки, открытом Мэттом Аустерном (в 1998 году!), num_get<>::get() не существует для short и int. Поэтому они были изменены для использования версии long и проверьте, что число чтения попадает в правильный диапазон.

Отчет о дефекте здесь.

(На самом деле не объясняют, почему они не думали, что могут сохранить первоначальное намерение, но именно поэтому эта часть Стандарта была изменена.)

Ответ 2

Это больше ++ путь C делать вещи для хранения нуля ресовавшегося const ссылки входного x затем возвращение исходного значения в случае ошибки.

Чтобы сохранить исходное значение в случае ошибки, библиотеке пришлось бы работать с временным. Он не может просто использовать пространство, предоставляемое x, без сохранения исходного значения где-нибудь. Тогда, возможно, также потребуется сделать копию в x в какой-то момент после того, как будут известны условия ошибки. Как еще вы получите исходное значение, если в противном случае есть ошибка или ввод для чтения. Поэтому каждый платит цену независимо от того, хотят ли они этого поведения или нет.

Поэтому возвращение исходного значения в случае ошибки не является С++ вообще. Если вы хотите, чтобы это поведение просто оплачивалось самим собой - создайте временное и передайте ссылку на const не const, например:

int x = 1;
int temp;
if (std::cin >> temp) 
    x = temp;
return x;