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
oconst char*
) son manejados por las sobrecargas que no son miembros deloperator<<
. 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
...
- 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.