131 votes

A quoi sert un "+" unaire avant un appel aux membres de std::numeric_limits<unsigned char> ?

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 comprend pas l'opérateur "+" dans

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

Je l'ai testé et remplacé par "-", ce qui a également fonctionné. Quelle est l'utilité d'un tel opérateur "+" ?

3 votes

Essayez-le. Qu'est-ce que vous obtenez si vous laissez de côté le + ?

4 votes

Cette question ne serait pas besoin de à demander si l'auteur du code se soucie d'expliquer ce que cela signifie ou d'utiliser un cast explicite à la place...

0 votes

Si vous le remplacez par - alors les sorties ne seront pas les valeurs correctes pour les limites

137voto

Joachim Pileborg Points 121221

L'opérateur de sortie << lorsqu'on lui transmet un char (signé ou non signé) l'écrira en tant que caractère .

Ces fonctions renverront des valeurs de type unsigned char . Et comme indiqué ci-dessus, cela imprimera les caractères que ces valeurs représentent dans l'encodage actuel, et non leurs valeurs entières.

Le site + L'opérateur convertit le unsigned char retourné par ces fonctions à un int par le biais de promotion entière . Ce qui signifie que les valeurs entières seront imprimées à la place.

Une expression comme +std::numeric_limits<unsigned char>::lowest() est essentiellement égal à static_cast<int>(std::numeric_limits<unsigned char>::lowest()) .

38voto

StoryTeller Points 6139

+ est là pour transformer le unsigned char dans un int . Le site + L'opérateur conserve la valeur, mais il a pour effet d'induire une promotion intégrale sur son opérande. Il s'agit de s'assurer que vous voyez une valeur numérique au lieu d'un caractère (semi-)aléatoire que operator << s'imprimerait si on lui donnait un type de caractère.

19voto

P.W Points 3960

Juste pour ajouter une référence aux réponses déjà données. Extrait du projet de norme CPP N4713 :

8.5.2.1 Opérateurs unaires
...

  1. L'opérande de l'opérateur unaire + doit être de type arithmétique, énumération non scopée ou pointeur et le résultat est la valeur de l'argument. La promotion intégrale est effectuée sur les opérandes intégraux ou d'énumération. Le type du résultat est le type de l'opérande promu.

Et char , short , int y long sont des types intégraux.

12voto

Lưu Vĩnh Phúc Points 3183

Sans + le résultat sera différent. L'extrait suivant produit a 97 au lieu de a a

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

La raison en est que différentes surcharges impriment différents types de données . Il n'y a pas basic_ostream& operator<<( char value ); surcharge pour std::basic_ostream et c'est expliqué à la fin de la page

Les arguments de type caractère et chaîne de caractères (par exemple, de type char o const char* ) sont traitées par le surcharges de non-membres de operator<< . Tenter de sortir un caractère en utilisant la syntaxe d'appel de fonction membre (par exemple, std::cout.operator<<('c'); ) appellera l'une des surcharges (2-4) et produira la valeur numérique. . Si l'on tente de produire une chaîne de caractères en utilisant la syntaxe d'appel de la fonction membre, la surcharge (7) sera appelée et la valeur du pointeur sera imprimée à la place.

Le site surcharge pour les non-membres qui sera appelé lorsque vous passez un char La variable est

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

qui imprime le caractère au point de code ch

Donc, en gros, si vous passez char , signed char o unsigned char directement dans le flux, il imprimera le caractère. Si vous essayez de supprimer le + sur les lignes ci-dessus, vous verrez qu'il imprime des caractères "étranges" ou non visibles, ce qui n'est pas ce que l'on attendrait.

Si vous souhaitez obtenir leurs valeurs numériques, vous devez appeler la surcharge de la fonction short , int , long o long long . La façon la plus simple de le faire est de promouvoir à partir de char à int avec un plus unaire + . C'est l'une des rares applications utiles de la opérateur unaire plus . Un transfert explicite vers int fonctionnera également

Il y a beaucoup de gens qui ont rencontré ce problème sur SO comme

1 votes

Vous vouliez dire unaire plus et non pas moins ?

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X