c++ char unary-operator

c++ - ¿Cuál es el propósito de un "+" único antes de una llamada a los miembros std:: numeric_limits<unsigned char>?



unary-operator (4)

Vi este ejemplo en la documentación de cppreference para std::numeric_limits

#include <limits> #include <iostream> int main() { std::cout << "type/tlowest()/tmin()/t/tmax()/n/n"; std::cout << "uchar/t" << +std::numeric_limits<unsigned char>::lowest() << ''/t'' << ''/t'' << +std::numeric_limits<unsigned char>::min() << ''/t'' << ''/t'' << +std::numeric_limits<unsigned char>::max() << ''/n''; std::cout << "int/t" << std::numeric_limits<int>::lowest() << ''/t'' << std::numeric_limits<int>::min() << ''/t'' << std::numeric_limits<int>::max() << ''/n''; std::cout << "float/t" << std::numeric_limits<float>::lowest() << ''/t'' << std::numeric_limits<float>::min() << ''/t'' << std::numeric_limits<float>::max() << ''/n''; std::cout << "double/t" << std::numeric_limits<double>::lowest() << ''/t'' << std::numeric_limits<double>::min() << ''/t'' << std::numeric_limits<double>::max() << ''/n''; }

No entiendo el operador "+" en

<< +std::numeric_limits<unsigned char>::lowest()

Lo he probado, lo reemplacé con "-", y eso también funcionó. ¿Cuál es el uso de tal operador "+"?


El operador de salida << al pasar un char (firmado o sin firmar) lo escribirá como un carácter .

Esas funciones devolverán valores de tipo unsigned char . Y como se señaló anteriormente, se imprimirán los caracteres que representan esos valores en la codificación actual, no sus valores enteros.

El operador + convierte el unsigned char devuelto por esas funciones a un int través de la promoción de enteros . Lo que significa que los valores enteros se imprimirán en su lugar.

Una expresión como +std::numeric_limits<unsigned char>::lowest() es esencialmente igual a static_cast<int>(std::numeric_limits<unsigned char>::lowest()) .


Sin + el resultado será diferente. El siguiente fragmento de código genera a 97 lugar de aa

char ch = ''a''; std::cout << ch << '' '' << +ch << ''/n'';

La razón es porque diferentes sobrecargas imprimen diferentes tipos de datos . No hay basic_ostream& operator<<( char value ); sobrecarga para std::basic_ostream y se explica al final de la página

Los argumentos de cadena de caracteres y caracteres (por ejemplo, de tipo char o const char* ) son manejados por las sobrecargas que no son miembros del operator<< . El intento de generar un carácter utilizando la sintaxis de llamada de la función miembro (por ejemplo, std::cout.operator<<(''c''); ) llamará a una de las sobrecargas (2-4) y generará el valor numérico . El intento de generar una cadena de caracteres utilizando la sintaxis de llamada de la función miembro llamará sobrecarga (7) e imprimirá el valor del puntero en su lugar.

La sobrecarga del no miembro que se llamará cuando pase una variable char es

template< class CharT, class Traits> basic_ostream<CharT,Traits>& operator<<( basic_ostream<CharT,Traits>& os, char ch );

que imprime el carácter en el punto de código ch

Básicamente, si pasas char , char signed char o unsigned char directamente al flujo, se imprimirá el carácter. Si intenta eliminar el signo + en las líneas anteriores, verá que imprime algunos caracteres "extraños" o no visibles, lo que no es lo que uno esperaría.

Si desea que sus valores numéricos en su lugar, debe llamar a la sobrecarga para short , int , long o long long . La forma más fácil de hacerlo es promocionando desde char a int con unary plus + . Esa es una de las raras aplicaciones útiles del operador unario plus . Un reparto explícito a int también funcionará

Hay muchas personas que enfrentaron ese problema en SO como

  • cout no imprime caracteres sin firmar
  • std :: cout deal with uint8_t como un personaje
  • uint8_t no se puede imprimir con cout

Solo para agregar una referencia a las respuestas ya dadas. Del borrador de trabajo estándar CPP N4713 :

8.5.2.1 Operadores unarios
...

  1. El operando del operador unario + tendrá aritmética, enumeración sin ámbito o tipo de puntero y el resultado es el valor del argumento. La promoción integral se realiza en operandos integrales o de enumeración. El tipo del resultado es el tipo del operando promovido.

Y char , short , int , y long son tipos integrales.


+ está ahí para convertir el unsigned char en un int . El operador + conserva el valor, pero tiene el efecto de inducir una promoción integral en su operando. Es para asegurarse de que ve un valor numérico en lugar de algún carácter (semi) aleatorio que el operator << imprimirá cuando se le asigne un tipo de carácter.