Qual è lo scopo di un "+" unario prima di una chiamata ai membri std :: numeric_limits <unsigned char>?


130

Ho visto questo esempio nella documentazione di cppreference perstd::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';
}

Non capisco l'operatore "+" in

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

L'ho testato, sostituito con "-" e anche quello ha funzionato. A che serve un tale operatore "+"?


3
Provalo. Cosa ottieni se lasci fuori il +?
Pete Becker,

4
Questa domanda non dovrebbe essere chiesta se lo scrittore del codice si preoccupa di spiegare cosa significa o utilizzare invece un cast esplicito ...
user202729

se si sostituisce con -allora le uscite non saranno i valori corretti per i limiti
phuclv

1
Per la cronaca, se vuoi Google questo genere di cose in te stesso, questo si chiama operatore "unario più" - è unario perché prende un singolo valore (in questo caso, la cosa subito dopo) e "più "è il modo di dire di Google +. In questo caso, la query sarà probabilmente "c ++ unary plus". È ... non esattamente intuitivo e devi ancora imparare a leggere la documentazione che troverai, ma l'IMO è un'abilità utile da coltivare.
Fondo Monica's Lawsuit,

Risposte:


137

L'operatore di output <<quando viene passato a char(firmato o non firmato) lo scriverà come carattere .

Quella funzione restituirà valori di tipo unsigned char. E come notato sopra che stamperà i caratteri che quei valori rappresentano nella codifica corrente, non i loro valori interi.

L' +operatore converte il valore unsigned charrestituito da tali funzioni in una promozioneint tramite numero intero . Ciò significa che verranno invece stampati i valori interi.

Un'espressione simile +std::numeric_limits<unsigned char>::lowest()è essenzialmente uguale a static_cast<int>(std::numeric_limits<unsigned char>::lowest()).


37

+è lì per trasformare il unsigned charin un int. L' +operatore mantiene il valore, ma ha l'effetto di indurre una promozione integrale sul suo operando. È per assicurarsi di vedere un valore numerico anziché un carattere (semi) casuale che operator <<verrebbe stampato quando viene assegnato un tipo di carattere.


18

Solo per aggiungere un riferimento alle risposte già fornite. Dalla bozza di lavoro standard CPP N4713 :

8.5.2.1 Operatori unari
...

  1. L'operando dell'operatore unario + deve avere aritmetica, enumerazione senza ambito o tipo di puntatore e il risultato è il valore dell'argomento. La promozione integrale viene eseguita su operandi di enumerazione o integrale. Il tipo di risultato è il tipo di operando promosso.

E char, short, int, e longsono tipi integrali.


12

Senza +il risultato sarà diverso. Il seguente frammento restituisce a 97invece dia a

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

Il motivo è perché sovraccarichi diversi stampano diversi tipi di dati . Non c'è basic_ostream& operator<<( char value );sovraccarico per std::basic_ostreamed è spiegato alla fine della pagina

Gli argomenti di stringa di caratteri e caratteri (ad es. Di tipo charo const char*) sono gestiti dai sovraccarichi non membri di operator<<. Il tentativo di emettere un carattere utilizzando la sintassi della chiamata della funzione membro (ad es. std::cout.operator<<('c');) Chiamerà uno dei sovraccarichi (2-4) e genererà il valore numerico . Il tentativo di generare una stringa di caratteri utilizzando la sintassi della chiamata della funzione membro chiamerà overload (7) e stamperà invece il valore del puntatore.

Il sovraccarico non membro che verrà chiamato quando si passa una charvariabile è

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

che stampa il personaggio nel punto di codice ch

Quindi sostanzialmente se passi char, signed charo unsigned chardirettamente allo stream, stamperà il personaggio. Se provi a rimuovere le +righe sopra riportate vedrai che stampa alcuni caratteri "strani" o non visibili che non è quello che ti aspetteresti

Se si desidera che i loro valori numerici, invece è necessario chiamare il sovraccarico per short, int, longo long long. Il modo più semplice per farlo è promuovere da chara intcon unary plus +. Questa è una delle rare utili applicazioni dell'operatore unary plus . Un cast esplicito intfunzionerà anche

Ci sono molte persone che hanno affrontato quel problema su SO


1
Intendevi unario più , non meno?
Ruslan,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.