std::istream::operator>> 处理无符号类型时,如何区分提取失败与下溢?

With std::istream::operator>> working on unsigned types, how do I tell apart a failed extraction from an underflow?

我想使用 std::istream::operator>> 将数据提取为无符号类型(在模板中,因此它可以是 ushort、uint 等)。具体来说,我使用 std::stringstream 来解析从具有 std::getline() 调用的文件中提取的 std::string 行。

由于我正在从文件中读取数据,因此这些提取可能会因不同原因而失败:下溢、溢出和 "bad extraction"。此类情况由 STL 处理:

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::max() or std::numeric_limits::min() is written and failbit flag is set.

source: cppreference

问题:std::numeric_limits::min() 对于无符号类型等于 0,因此无法知道我正在读取的内容是否不是整数(在这种情况下我正在中止程序)或如果它只是下溢(在这种情况下,我只是限制值并发出警告)。

如何在不使用我正在使用的无符号类型的更大 and/or 有符号等价物的情况下解决这个问题?

无符号类型不会下溢。如果您通过输入负数表示 "underflow",则标准流不会将其视为错误。负数环绕成无符号类型,并且 failbit 未设置。

因此,如果您看到存储了 0 并且设置了 failbit,您可以断言这是提取失败。要检测负数错误,您必须做一些额外的工作。例如,您可以先读取一个(足够大的)有符号整数类型的值来检测它是否为负数。