为什么std::( i)ostream将带符号/无符号字符视为文本而不是整数? [英] Why std::(i)ostream treat signed / unsigned char as a text and not an integer?

查看:192
本文介绍了为什么std::( i)ostream将带符号/无符号字符视为文本而不是整数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

此代码没有执行应做的事情:

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_tunsigned 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 <<.

我的问题:

  1. 标准是否要求这种行为(流操作符将有符号/无符号字符视为字符类型,而不是整数)? 如果是,则:
  1. Is this behavior (streaming operators treating signed / unsigned char as character type and not an integer) required by the standard? If it is then:
  1. 这种违反直觉的语义背后的原理是什么?
  2. 应该认为这是一个缺陷吗,是否有提议来更改这种语义?

我可能应该添加一些解释,为什么我认为这违反直觉. 尽管类型名称包含单词char,但是signedunsigned部分指定了特定的整数语义,并且这些类型通常用作字节大小的整数.甚至标准也通过它们定义了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 charsigned 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 <<对于charunsigned charsigned 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屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆