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

Взять из: cppreference

До C++11:

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

Начиная с C++11:

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

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

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

в случае сбоя числового преобразования вернется 1 до C++ 11 и 0 иначе.

Зачем комитет по стандартизации вводит такие тонкие изменения? Или, скорее, какой код был возможен до C++ 11, который гарантировал это изменение?

2 ответа

Решение

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

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

Отчет о дефектах находится здесь.

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

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

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

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

int x = 1;
int temp;
if (std::cin >> temp) 
    x = temp;
return x;
Другие вопросы по тегам