Questo codice non fa quello che dovrebbe fare:Perché std: :(i) ostream considera il carattere firmato/non firmato come un testo e non un intero?
#include <iostream>
#include <cstdint>
int main()
{
uint8_t small_integer;
std::cin >> small_integer;
std::cout << small_integer;
}
La ragione è semplice: uint8_t
è un typedef per unsigned char
e flussi di trattare questo tipo come testo:
Visual C++ 2015 implementazione
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);
}
e un codice simile con cast char
per operator <<
.
Le mie domande:
- E` questo comportamento (streaming operatori trattando un signed/unsigned char come tipo di carattere e non un intero) richiesto dalla norma? Se è così:
- Qual è la logica alla base di tale semantica poco intuitiva?
- Se questo fosse considerato un difetto, c'erano proposte per cambiare questa semantica?
forse dovrei aggiungere un po 'di spiegazione perché ritengo controintuitivo. Sebbene il nome del tipo contenga la parola char, la parte signed
o unsigned
specifica una particolare semantica integer e tali tipi vengono generalmente utilizzati come numeri interi in byte. Anche lo standard definisce int8_t
/uint8_t
attraverso di loro.
UPD: La questione è sul comportamento di sovraccarichi operatore di streaming per unsigned char
e signed char
.
È fastidioso. Ho usato la mia propria funzione to_string che tratta (u) int8_t come interi mentre tratta il carattere come un carattere. Ho aggiunto specializzazioni separate per uint8_t, int8_t e char dal momento che presumo che sia perfettamente valido per coloro che non devono essere di tre tipi distinti. – Matt
Non è una risposta alla tua domanda, ma ['std :: byte'] (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0257r0.pdf) è stato proposto di superare questo problema. – Praetorian
@Praetorian, mentre questa è davvero una proposta interessante, affronta un problema assolutamente diverso. –