C++ C++;失败时
摘自: 在C++11之前: 如果提取失败(例如,如果在预期数字的位置输入字母),则该值保持不变,并设置failbit 从C++11开始: 若提取失败,则将零写入值并设置failbit。如果提取导致值太大或太小而无法装入值,则会写入C++ C++;失败时,c++,c++11,C++,C++11,摘自: 在C++11之前: 如果提取失败(例如,如果在预期数字的位置输入字母),则该值保持不变,并设置failbit 从C++11开始: 若提取失败,则将零写入值并设置failbit。如果提取导致值太大或太小而无法装入值,则会写入std::numeric\u limits::max()或std::numeric\u limits::min(),并设置failbit标志 由于此更改,这意味着以下代码段: int x = 1; std::cin >> x; return x; 如果数字
std::numeric\u limits::max()
或std::numeric\u limits::min()
,并设置failbit标志
由于此更改,这意味着以下代码段:
int x = 1;
std::cin >> x;
return x;
如果数字转换失败,将在C++11之前返回1
,否则返回0
为什么标准委员会会引入如此微妙的突破性变化?或者更确切地说,在C++11之前,什么样的代码可以保证这种更改?看起来就像最初指定的那样,
操作符在某些情况下被破坏了(即严格来说不可能存在)。
这就是“修复”
在2011年初的草案中,该标准在这方面与2003年基本相同。然而,在Matt Ostern(1998年!)打开的库缺陷报告中,num_get::get()
对于short
和int
不存在。
因此,他们被更改为使用long
版本,并检查读取的数字是否在正确的范围内
缺陷报告是
(实际上并不能解释为什么他们认为他们不能保留最初的行为,但这就是为什么标准的这部分被改变了)
< P>这是在非代码> const <代码>引用输入>代码> x>代码>中存储C++的方式。p>
为了在出现错误情况时保持原始值,库必须使用临时值。它不能简单地使用x
提供的空间,而不将原始值存储在某个地方。然后,一旦知道错误情况,它可能还必须在某个时间点复制到x
。如果出现错误或读取输入不正确,您将如何获取原始值。所以每个人都要付出代价,不管他们是否想要这种行为
在错误的情况下返回原始值根本不是C++。如果您想要这种行为,只需自己付费-创建一个临时变量,并将其非常量
引用传递给操作符>>
,类似于:
int x = 1;
int temp;
if (std::cin >> temp)
x = temp;
return x;
检查错误是你的责任。这是C++11之前的版本
和C++11
,也将出现在未来的版本中(最有可能)。这完全是你的错,因为你没有检查,而是依赖于一些实现细节。@stefan,这太荒谬了。期望未修改的值依赖于实现细节,但检查failbit不依赖于实现细节?世界跆拳道联盟?为什么我们甚至有接口规范和文档?您能否解释一下为什么在“如果提取失败(例如,如果输入了一个字母,其中需要一个数字),则未修改值并设置failbit。”中,“未修改值”部分是一个实现细节,但“设置了failbit”部分不是?您不能有选择地选择记录的行为并称之为实现细节。@stefan否。它绝对不是实现细节。这是操作符>>
的指定行为。它就写在规范中。您有选择地忽略操作符>>
的指定行为的其他哪些部分?@stefan我的观点是:如果您希望它在出错时返回1,那么代码是完全正确的。嗯,是的。规范以不兼容的方式更改并不是编写代码的人的错。另请参阅。表面上看,我们似乎无法真正依赖这种行为,所以实际上这并不是什么大损失。这还不包括这个问题所涉及的num_get::get第3阶段的变化。我认为更好的链接是同样的第23期document@Cubbi:就是这个:)