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

130

Vi este ejemplo en la documentación de cppreference parastd::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 probé, lo reemplacé con "-", y eso también funcionó. ¿De qué sirve ese operador "+"?

Zhang
fuente
3
Intentalo. ¿Qué obtienes si dejas de lado +?
Pete Becker
44
Esta pregunta no tendría que hacerse si el escritor del código se preocupa por explicar lo que significa o usar un reparto explícito en su lugar ...
user202729
si reemplaza con, -entonces las salidas no serán los valores correctos para los límites
phuclv
1
Para el registro, si desea Google este tipo de cosas en sí mismo, esto se llama el operador "unario más": es unario porque toma un solo valor (en este caso, lo que está justo después) y "más "es la forma de decir de Google +. En este caso, su consulta probablemente sería "c ++ unary plus". No es ... exactamente intuitivo, y aún tiene que aprender a leer la documentación que encontrará, pero IMO es una habilidad útil para cultivar.
Financia la demanda de Mónica el

Respuestas:

137

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

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

El +operador convierte lo unsigned chardevuelto por esas funciones en una promoción de entero aint través . 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()).

Algún tipo programador
fuente
37

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

StoryTeller - Unslander Monica
fuente
18

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

8.5.2.1 Operadores unarios
...

  1. El operando del operador unario + tendrá una aritmética, una enumeración sin ámbito o un 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 promocionado.

Y char, short, int, y longson tipos integrales.

PW
fuente
12

Sin +el resultado será diferente. Las siguientes salidas de fragmentos en a 97lugar dea a

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 std::basic_ostreamy se explica al final de la página.

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

La sobrecarga de no miembros que se llamará cuando pase una charvariable es

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

que imprime el personaje en el punto de código ch

Básicamente, si pasa char, signed charo unsigned chardirectamente a la transmisión, imprimirá el personaje. Si intenta eliminar el +en las líneas anteriores, verá que imprime algunos caracteres "extraños" o no visibles, que no es lo que cabría esperar

Si desea que sus valores numéricos en lugar usted debe llamar a la sobrecarga de short, int, longo long long. La forma más fácil de hacer esto es promocionar de chara intcon unary plus +. Esa es una de las raras aplicaciones útiles del operador unario plus . Un elenco explícito para inttambién funcionará

Hay muchas personas que enfrentaron ese problema en SO como

phuclv
fuente
1
¿Quiso decir unario más , no menos?
Ruslan