为什么std::( i)ostream将带符号/无符号字符视为文本而不是整数? [英] Why std::(i)ostream treat signed / unsigned char as a text and not an integer?
问题描述
此代码没有执行应做的事情:
This code doesn't do what it's supposed to do:
#include <iostream>
#include <cstdint>
int main()
{
uint8_t small_integer;
std::cin >> small_integer;
std::cout << small_integer;
}
原因很简单:uint8_t
是unsigned char
的typedef,流将此类型视为文本:
Visual C ++ 2015实现
The reason is simple: uint8_t
is a typedef for unsigned char
and streams treat this type as a text:
Visual C++ 2015 implementation
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);
}
和类似的代码,其中operator <<
强制转换为char
.
And a similar code with cast to char
for operator <<
.
我的问题:
- 标准是否要求这种行为(流操作符将有符号/无符号字符视为字符类型,而不是整数)? 如果是,则:
- Is this behavior (streaming operators treating signed / unsigned char as character type and not an integer) required by the standard? If it is then:
- 这种违反直觉的语义背后的原理是什么?
- 应该认为这是一个缺陷吗,是否有提议来更改这种语义?
我可能应该添加一些解释,为什么我认为这违反直觉.
尽管类型名称包含单词char,但是signed
或unsigned
部分指定了特定的整数语义,并且这些类型通常用作字节大小的整数.甚至标准也通过它们定义了int8_t
/uint8_t
.
I should probably add a little explanation why I consider it counterintuitive.
Although the type name contains the word char, the signed
or unsigned
part specify particular integer semantic and those types are generally used as byte sized integers. Even the standard defines int8_t
/ uint8_t
through them.
UPD::问题是有关unsigned char
和signed char
的流运算符重载的行为.
UPD: The question is about behavior of streaming operator overloads for unsigned char
and signed char
.
推荐答案
标准(n3797)表示以下内容:
The standard (n3797) says the following:
27.7.2.2.3 basic_istream :: operator >>
template<class charT, class traits>
basic_istream<charT,traits>& operator>>(basic_istream<charT,traits>& in, charT& c);
template<class traits>
basic_istream<char,traits>& operator>>(basic_istream<char,traits>& in, unsigned char& c);
template<class traits>
basic_istream<char,traits>& operator>>(basic_istream<char,traits>& in, signed char& c);
12个作用:行为类似于in的格式化输入成员(如27.7.2.2.1中所述).构造哨兵对象后,从其中提取了一个字符,如果有的话,并存储在c.否则,该函数将调用in.setstate(failbit).
12 Effects: Behaves like a formatted input member (as described in 27.7.2.2.1) of in. After a sentry object is constructed a character is extracted from in, if one is available, and stored in c. Otherwise, the function calls in.setstate(failbit).
27.7.3.6.4字符插入器功能模板
// specialization
template<class traits>
basic_ostream<char,traits>& operator<<(basic_ostream<char,traits>& out, char c);
// signed and unsigned
template<class traits>
basic_ostream<char,traits>& operator<<(basic_ostream<char,traits>& out, signed char c);
template<class traits>
basic_ostream<char,traits>& operator<<(basic_ostream<char,traits>& out, unsigned char c);
1效果:表现为out的格式化输出函数(27.7.3.6.1).构造一个字符序列seq.如果c具有char类型且流的字符类型不是char,则 seq由out.widen(c);组成.否则seq由c 组成.按27.7.3.6.1中所述确定seq的填充.将seq插入out.调用os.width(0).
1 Effects: Behaves as a formatted output function ( 27.7.3.6.1) of out. Constructs a character sequence seq. If c has type char and the character type of the stream is not char, then seq consists of out.widen(c); otherwise seq consists of c. Determines padding for seq as described in 27.7.3.6.1. Inserts seq into out. Calls os.width(0).
第一个问题的答案是:是的,标准要求operator >>
和operator <<
对于char
,unsigned char
和signed char
的行为完全相同,即它们读/写单个字符,而不是整数.不幸的是,标准并不能解释原因.我希望有人能阐明2和3.
So the answer to the first question: yes, the standard requires that operator >>
and operator <<
behave exactly the same for char
, unsigned char
and signed char
, that is they read / write a single character, not an integer. Unfortunately, standard doesn't explain why. I hope someone will shed light on 2 and 3.
这篇关于为什么std::( i)ostream将带符号/无符号字符视为文本而不是整数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!