简体   繁体   English

故障时C ++中的istream行为更改

[英]istream behavior change in C++ upon failure

Take from: cppreference 来自: cppreference

Until C++11: 直到C ++ 11:

If extraction fails (eg if a letter was entered where a digit is expected), value is left unmodified and failbit is set. 如果提取失败(例如,如果在预期的数字中输入了字母),则值将保持不变,并设置故障位。

Since C++11: 从C ++ 11开始:

If extraction fails, zero is written to value and failbit is set. 如果提取失败,则将零写入值并设置故障位。 If extraction results in the value too large or too small to fit in value, std::numeric_limits<T>::max() or std::numeric_limits<T>::min() is written and failbit flag is set. 如果提取导致值太大或太小而无法容纳该值,则将std::numeric_limits<T>::max()std::numeric_limits<T>::min()写入并设置故障位标志。

Due to this change, this means that the following snippet: 由于此更改,这意味着以下代码段:

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

in the event that the numerical conversion fails, will return 1 before C++11, and 0 otherwise. 如果数值转换失败,将在C ++ 11之前返回1 ,否则返回0

Why would the standard committee introduce such a subtle breaking change? 标准委员会为什么要引入如此微妙的突破性变化? Or rather, what kind of code was possible prior to C++11 that warranted this change? 或者更确切地说,在C ++ 11之前什么样的代码可以保证进行此更改?

It seems as originally specified, the operator>> s were broken in some cases (ie strictly speaking couldn't exist). 似乎像最初指定的那样,在某些情况下, operator>>是坏掉的(即严格来说是不存在的)。 This is the "fix". 这是“修复”。

In a draft from early 2011, The Standard is basically the same in this regard as it was in 2003. However, in a library defect report opened by Matt Austern (in 1998!), num_get<>::get() doesn't exist for short and int . 在2011年初的草案中,标准在这方面与2003年基本相同。但是,在Matt num_get<>::get()打开的库缺陷报告(于1998年!)中, num_get<>::get()并没有存在于shortint So they were changed to use the long version, and check the read number falls within the correct range. 因此将它们更改为使用long版本,并检查读取的数量是否在正确的范围内。

The defect report is here . 缺陷报告在这里

(Doesn't really explain why they didn't think they could keep the originally intended behaviour, but it is why this part of The Standard was changed.) (并没有真正解释他们为什么不认为自己可以保留最初打算的行为,但这就是为什么本标准的这一部分被更改的原因。)

It's more the C++ way of doing things to store zero in the non- const reference input x then returning the original value in case of error. C ++的处理方式更多是将零存储在非const引用输入x然后在出现错误的情况下返回原始值。

In order to keep the original value in case of an error condition the library would have to work with a temporary. 为了在发生错误的情况下保留原始值,该库必须使用临时库。 It can't simply use the space provided by x without storing the original value somewhere. 它不能简单地使用x提供的空间而不将原始值存储在某个地方。 Then it might also have to do a copy to x at some point once the error conditions are known. 一旦知道了错误条件,它有时也可能必须复制到x How else would you get the original value if there's an error or the read input otherwise. 如果出现错误,否则将如何获取原始值? So everyone pays the price regardless of whether they want this behavior or not. 因此,无论是否需要这种行为,每个人都付出代价。

So returning the original value in case of error isn't C++ at all. 因此,发生错误时返回原始值根本不是C ++。 If you want that behavior simply pay for it yourself - create a temporary and pass its non- const reference to operator>> , something like: 如果您想让这种行为简单地自己付钱-创建一个临时文件并将其非const引用传递给operator>> ,例如:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM