根据这些问题的答案,所有基本整数类型的重载是否足以捕获所有整数?所有基本类型的重载可能无法处理int8_t
、int64_t
等类型。另一方面,根据文档std::ostream格式化的输出和std::istream格式的输入是通过重载所有基本类型来实现的。那么,在int8_t
和其他无法通过这种重载处理的平台上,C++流必须如何处理它们呢?它会编译失败吗?标准库实现者是否必须提供额外的未记录的方法?还有别的吗?
对于整数类型,[istream]定义:
basic_istream<charT,traits>& operator>>(bool& n);
basic_istream<charT,traits>& operator>>(short& n);
basic_istream<charT,traits>& operator>>(unsigned short& n);
basic_istream<charT,traits>& operator>>(int& n);
basic_istream<charT,traits>& operator>>(unsigned int& n);
basic_istream<charT,traits>& operator>>(long& n);
basic_istream<charT,traits>& operator>>(unsigned long& n);
basic_istream<charT,traits>& operator>>(long long& n);
basic_istream<charT,traits>& operator>>(unsigned long long& n);
如果x
是不在该列表中的整数类型,则任何形式为is >> x
的代码都可能无法编译。
作为实现质量问题,提供扩展整数类型的实现可能会为这些类型添加operator>>
重载。这是[member.functions]/2允许的(正如hvd在评论中所指出的),谈论标准库中的类:
实现可以在类中声明额外的非虚拟成员函数签名:
[…]
- 通过为成员函数名称添加成员函数签名
对C++标准库中描述的成员函数签名的调用的行为就像实现没有声明其他成员函数签名一样。
这是一个比一般规则更有力的保证,即实现可以添加不会破坏一致性程序的扩展。使用SFINAE的合格程序的行为可能会受到额外过载的影响。
对于输出,不在列表中的整数类型将隐式转换为列表中的另一个整数类型。
那么,在
int8_t
和其他无法通过这种重载处理的平台上,C++流必须如何处理它们呢?
就整数插入而言(运算符<<),它将根据标准C++重载分辨率来处理它们。扩展整数类型是仍然的整数类型,并遵循隐式转换规则以解决重载问题。
例如,int8_t
可以上转换为任何大到足以容纳它的有符号整数类型。因此,如果int8_t
是扩展整数类型,而不是标准整数类型的别名,则可以根据重载解析规则将其上转换为标准整数类型之一。
对于整数提取(operator>>
),这需要对活动整数的非const
引用,因此无法进行转换。因此,如果您没有提供operator>>
重载的显式类型之一,那么您的代码应该无法编译。
如果一个实现专门为这些类型添加重载,那么你可能会得到最好的结果,但你不能依赖它。
应该注意的是,C++17的新CCD_ 13和CCD_;无符号整数类型(和char
)。因此,这包括扩展整数类型。
它会编译失败吗?
对于插入,这取决于使用的类型。int8_t
是安全的,因为有比它大的标准整数类型。它的行为可能与您预期的不同,但它会起作用。
相反,不能保证int_least64_t
或intmax_t
不大于long long
。隐式转换不能从大到小。在这种情况下,会出现编译错误。
对于提取,如果类型不匹配,则会导致编译失败。
标准库实现者是否必须提供额外的未记录方法?
否。他们被允许这样做,但这不是你可以依赖的
int8_t
是一个特殊的情况,因为它是如何实现的。
CCD_ 21用作字节大小类型和字符类型的双重占空比。因为它是一个字符类型,iostream操作将以不同于处理整数类型的方式处理char
的使用。对于整数,它将解析/生成整数字符串。对于一个字符,它假设你想读一个字符。
int8_t
的有效实现可以是signed char
的别名,或者如果它是签名的,则仅是char
。因此,将其与流操作一起使用将将其视为字符。
int8_t
的有效实现可以是扩展整数类型,该类型与char
不同。因此,根据重载解析规则,该值将被上转换为与标准整数类型之一匹配的较大整数类型。因此,它将调用其中一个。