26

取自:cppreference

直到 C++11:

如果提取失败(例如,如果在需要数字的地方输入了一个字母),则值保持不变并设置失败位。

从 C++11 开始:

如果提取失败,则将零写入 value 并设置 failbit。如果提取导致值太大或太小而无法容纳在值中,std::numeric_limits<T>::max()或者std::numeric_limits<T>::min()被写入并设置了失败位标志。

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

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

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

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

4

2 回答 2

7

看起来就像最初指定的那样,operator>>在某些情况下 s 被破坏(即严格来说不存在)。这就是“修复”。

在 2011 年初的草案中,该标准在这方面与 2003 年基本相同。但是,在 Matt Austern(1998 年!)打开的库缺陷报告中,num_get<>::get()不存在shortint. 所以他们被改成使用long版本,并检查读取数是否在正确的范围内。

缺陷报告在这里

(并没有真正解释为什么他们认为他们不能保持最初的预期行为,但这就是标准的这一部分被改变的原因。)

于 2013-10-22T16:12:27.820 回答
2

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

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

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

int x = 1;
int temp;
if (std::cin >> temp) 
    x = temp;
return x;
于 2016-01-08T04:44:46.533 回答