失败时C ++中的istream行为改变

时间:2013-10-22 15:45:49

标签: c++ c++11

取自:cppreference

直到C ++ 11:

  

如果提取失败(例如,如果输入了预期数字的字母),则值保持不变,并设置failbit。

从C ++ 11开始:

  

如果提取失败,则将零写入值并设置failbit。如果提取结果的值太大或太小而不适合值,则会写入std::numeric_limits<T>::max()std::numeric_limits<T>::min()并设置failbit标志。

由于此更改,这意味着以下代码段:

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

如果数字转换失败,将在C ++ 11之前返回1,否则返回0

为什么标准委员会会引入这种微妙的突破性变化?或者更确切地说,在C ++ 11之前可以使用哪种代码来保证这种变化?

2 个答案:

答案 0 :(得分:7)

似乎最初指定的是operator>>在某些情况下被打破(即严格来说不可能存在)。 这是“修复”。

在2011年初的草案中,标准在这方面与2003年基本相同。但是,在Matt Austern(1998年)开设的图书馆缺陷报告中,num_get<>::get()没有存在shortint。 因此,他们被更改为使用long版本,并检查读取的数字是否在正确的范围内。

缺陷报告为here

(没有真正解释为什么他们不认为他们可以保留原先预期的行为,但这就是为什么标准的这一部分被改变了。)

答案 1 :(得分:2)

更多的C ++方法是在非const引用输入x中存储零,然后在出错时返回原始值。

为了在出现错误情况时保留原始值,库必须使用临时值。它不能简单地使用x提供的空间而不在某处存储原始值。然后,一旦知道错误条件,它可能还必须在某个时刻复制到x。如果出现错误或读取输入,您将如何获得原始值。所以无论他们是否想要这种行为,每个人都要付出代价。

因此,在出现错误时返回原始值根本不是C ++。如果你想要这种行为只需自己付费 - 创建一个临时的并将其非const引用传递给operator>>,例如:

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