【发布时间】:2016-04-25 14:34:25
【问题描述】:
这段代码没有做它应该做的事情:
#include <iostream>
#include <cstdint>
int main()
{
uint8_t small_integer;
std::cin >> small_integer;
std::cout << small_integer;
}
原因很简单:uint8_t 是 unsigned char 的类型定义,流将这种类型视为文本:
Visual C++ 2015 实现
template<class _Traits> inline
basic_istream<char, _Traits>& operator>>(
basic_istream<char, _Traits>& _Istr, unsigned char& _Ch)
{ // extract an unsigned char
return (_Istr >> (char&)_Ch);
}
还有一个类似的代码,将char 转换为operator <<。
我的问题:
- 标准是否要求这种行为(流式操作符将有符号/无符号字符视为字符类型而不是整数)?
如果是那么:
- 这种违反直觉的语义背后的基本原理是什么?
- 这是否应该被视为缺陷,是否有建议更改此语义?
我可能应该添加一点解释,为什么我认为它违反直觉。
尽管类型名称包含单词 char,但 signed 或 unsigned 部分指定了特定的整数语义,并且这些类型通常用作字节大小的整数。甚至标准都通过它们定义了int8_t/uint8_t。
UPD:问题是关于unsigned char 和signed char 的流式运算符重载的行为。
【问题讨论】:
-
这很烦人。我使用了自己的 to_string 函数,它将 (u)int8_t 视为整数,同时将 char 视为字符。我为 uint8_t、int8_t 和 char 添加了单独的特化,因为我假设它对于那些不是三种不同类型的完全有效。
-
不是您的问题的答案,但已提议使用
std::byte来解决此问题。 -
@Praetorian,虽然这确实是一个有趣的提议,但它解决了一个完全不同的问题。
-
@Matt 我会假设编译器无法区分
int8_t和char作为参数列表中的类型。您的to_string是否真的按照您的预期工作? -
如果
int8_t或uint8_t是char的typedef 则不能工作,但如果它们是signed char和unsigned char的typedef 则可以工作。
标签: c++ language-lawyer