J'ai vu cet exemple dans la documentation de cppreference pour 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';
}
Je ne comprends pas l'opérateur "+" dans
<< +std::numeric_limits<unsigned char>::lowest()
Je l'ai testé, remplacé par "-", et cela a également fonctionné. A quoi sert un tel opérateur "+"?
L'opérateur de sortie <<
lorsqu'il reçoit un char
(signé ou non signé) l'écrira sous la forme d'un caractère .
Ces fonctions renverront des valeurs de type unsigned char
. Et comme indiqué ci-dessus, les caractères que ces valeurs représentent dans l’encodage actuel sont imprimés, pas leurs valeurs entières.
L'opérateur +
convertit le unsigned char
renvoyé par ces fonctions en une int
à promotion d'un entier . Ce qui signifie que les valeurs entières seront imprimées à la place.
Une expression comme +std::numeric_limits<unsigned char>::lowest()
est essentiellement égale à static_cast<int>(std::numeric_limits<unsigned char>::lowest())
.
+
est là pour transformer le unsigned char
en int
. L'opérateur +
préserve la valeur, mais il a pour effet d'induire une promotion intégrale sur son opérande. C'est pour s'assurer que vous voyez une valeur numérique au lieu d'un caractère (semi-) aléatoire que operator <<
imprimera lorsqu'un type de caractère lui est attribué.
Juste pour ajouter une référence aux réponses déjà données. D'après le brouillon standard du RPC N471 :
8.5.2.1 Opérateurs unaires
...
- L'opérande de l'opérateur unaire + doit avoir un type arithmétique, une énumération non délimitée ou un pointeur et le résultat correspond à la valeur de l'argument. La promotion intégrale est effectuée sur des opérandes d'intégration ou d'énumération. Le type du résultat est le type de l'opérande promu.
Et char
, short
, int
et long
sont des types entiers.
Sans _+
_, le résultat sera différent. L'extrait de code suivant génère _a 97
_ au lieu de _a a
_
_char ch = 'a';
std::cout << ch << ' ' << +ch << '\n';
_
La raison en est que des surcharges différentes impriment différents types de données . Il n'y a pas de surcharge basic_ostream& operator<<( char value );
pour std::basic_ostream
et c'est expliqué à la fin de la page.
Les arguments de caractères et de chaînes de caractères (par exemple, de type
char
ou _const char*
_) sont gérés par le surcharges non membres de _operator<<
_. Tenter de générer un caractère à l’aide de la syntaxe d’appel de la fonction membre (par exemple,std::cout.operator<<('c');
) appelle l’une des surcharges (2-4) et génère la valeur numérique . Tenter de générer une chaîne de caractères à l'aide de la syntaxe d'appel de fonction membre appelle overload (7) et affiche la valeur du pointeur à la place.
Le surcharge non-membre qui sera appelé lorsque vous passerez une variable char
est
_template< class CharT, class Traits> basic_ostream<CharT,Traits>& operator<<(
basic_ostream<CharT,Traits>& os, char ch );
_
qui affiche le caractère au point de code ch
Donc, si vous passez char
, _signed char
_ ou _unsigned char
_ directement au flux, le caractère sera imprimé. Si vous essayez de supprimer le _+
_ des lignes ci-dessus, vous verrez qu'il imprime des caractères "étranges" ou non visibles, ce qui n'est pas ce à quoi on pourrait s'attendre.
Si vous voulez plutôt leurs valeurs numériques, vous devez appeler la surcharge pour short
, int
, long
ou _long long
_. La méthode la plus simple consiste à passer de char
à int
avec unary plus _+
_. C'est l'un des applications utiles rares de opérateur unaire plus . Une conversion explicite en int
fonctionnera également
Il y a beaucoup de gens qui ont fait face à ce problème sur SO comme