usar tipos lenguaje leer declaracion datos como caracteres cadena c++ templates operator-overloading char cstdint

lenguaje - tipos de datos en c++



Cómo generar tipos char o<cstdint> sin firmar/firmados como enteros con<< en C++ (5)

Fondo:

Tengo operadores de secuencia de plantilla (por ejemplo, operator << (ostream &, std::vector <T>) ) (que operator << (ostream &, std::vector <T>) salida a elementos de contenedor que pueden ser de algún tipo entero de 8 bits, (por ejemplo, unsigned char , int_least8_t , etcétera) .

Problema:

El valor predeterminado es que estos tipos se envían como char (ASCII). Solo usé char (o wchar_t o lo que sea) para las variables ASCII, nunca para los tipos sin signo / firmado. ¿Cómo puedo hacer que estos otros tipos de 8 bits siempre se muestren como signed int / unsigned int (números) en su lugar, incluso cuando la persona que llama no conoce el tipo?

Primeros intentos:

He intentado (con GCC) por ejemplo definir el operator << (ostream &, unsigned char) con un molde en él (es decir, stream << static_cast <int> (value) . Eso funciona para los valores de unsigned char , pero luego uint8_t todavía se pone salida como un char .

El mismo tipo subyacente (es decir, el carácter unsigned/signed char no se puede usar en sobrecargas, por lo que no puedo definir una sobrecarga de, por ejemplo, el operator << (ostream &, int_fast8_t) .


Está confundiendo los datos reales contenidos en una variable, con la representación que elija para imprimirla.

Piénselo de esta manera: chars , ints , doubles , longs , whatevers, todos son solo trozos de memoria para que usted almacene números. Un char es un número entre 0 y 255 (o -128 y 127) - usted puede elegir representarlo como un personaje ASCII, o como un número, o como estrellas en el cielo con la ayuda de OpenGL.

Si desea ver el número detrás del carácter ''a'', simplemente pida a su programa que trate ese trozo de memoria (que para usted contiene una ''a'') como un número. Usar moldes Aquí:

http://www.cplusplus.com/doc/tutorial/typecasting/

¡Mira si eso ayuda!


Puedes lanzarlos antes de que los muestres:

std::cout << (unsigned int) container[index];


Si te he entendido bien ... déjalo así:

std::cout << ( unsigned int )char << ''/n'';

O más estilo c ++: use static_cast, por ejemplo:

int main() { char a = ''a''; char b = 97; std::cout << static_cast< unsigned int >( a ) << ''/n''; std::cout << static_cast< unsigned int >( b ) << ''/n''; return 0; }

both std::cout imprimirá lo mismo: el primero - el código ASCII de ''a'' : 97 , el segundo - solo el valor 97 , almacenado en b. Ambos, a y b , son absolutamente iguales.


Simplemente puedes lanzarlo:

#include<iostream> int main() { uint8_t blah = 65; std::cout << static_cast<int>(blah) << "/n"; return 0; }

sesenta y cinco


Una forma de pensar es usar rasgos de tipo para definir el tipo de salida para cada tipo. Tendría que declararlo para cada tipo a mano. Los rasgos se podrían definir como una estructura de plantilla que está especializada para cada tipo de datos que tiene un tipo de salida diferente al tipo de datos en sí:

template< T > struct output_trait { typedef const T & output_type; }

En tu operador escribes:

std::cout << static_cast< output_trait< T >::output_type >( variable ) << std::endl;

Esto no se lanzará por defecto, pero para los tipos para los que output_trait está especializado hará un cast:

template<> struct output_trait< unsigned char > { typedef unsigned int output_type; }