Was ist der Zweck eines unären "+" vor einem Aufruf von std :: numeric_limits <unsigned char> -Mitgliedern?

130

Ich habe dieses Beispiel in der Dokumentation von cppreference für gesehenstd::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';
}

Ich verstehe den Operator "+" in nicht

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

Ich habe es getestet, durch "-" ersetzt, und das hat auch funktioniert. Was nützt ein solcher "+" - Operator?

Zhang
quelle
3
Versuch es. Was bekommen Sie, wenn Sie das weglassen +?
Pete Becker
4
Diese Frage würde nicht brauchen Fragesteller , wenn der Schreiber der Code Sorgen zu sein , zu erklären , was es bedeutet oder eine explizite Umwandlung verwenden Sie stattdessen ...
user202729
Wenn Sie durch ersetzen, werden -die Ausgänge nicht die richtigen Werte für die Grenzwerte sein
phuclv
1
Wenn Sie diese Art von Dingen in sich selbst googeln möchten, wird dies als "unäres Plus" -Operator bezeichnet - es ist unär, weil es einen einzelnen Wert (in diesem Fall das Ding direkt danach) und "plus" annimmt "ist die Google-freundliche Art zu sagen +. In diesem Fall wäre Ihre Abfrage wahrscheinlich "c ++ unary plus". Es ist ... nicht gerade intuitiv und Sie müssen noch lernen, die Dokumentation zu lesen, die Sie finden, aber IMO ist es eine nützliche Fähigkeit, sich zu kultivieren.
Fund Monica Klage

Antworten:

137

Der Ausgabeoperator schreibt <<ein char(vorzeichenbehaftetes oder vorzeichenloses) Zeichen als Zeichen .

Diese Funktion gibt Werte vom Typ zurück unsigned char. Und wie oben erwähnt, werden die Zeichen gedruckt, die diese Werte in der aktuellen Codierung darstellen, nicht ihre ganzzahligen Werte.

Der +Operator konvertiert die unsigned charvon diesen Funktionen zurückgegebenen in eine intdurchgehende Ganzzahl-Heraufstufung . Dies bedeutet, dass stattdessen die ganzzahligen Werte gedruckt werden.

Ein Ausdruck wie +std::numeric_limits<unsigned char>::lowest()ist im Wesentlichen gleich static_cast<int>(std::numeric_limits<unsigned char>::lowest()).

Ein Programmierer
quelle
37

+ist da, um das unsigned charin ein zu verwandeln int. Der +Operator ist werterhaltend, bewirkt jedoch eine integrale Förderung seines Operanden. Stellen Sie sicher, dass Sie einen numerischen Wert anstelle eines (halb-) zufälligen Zeichens sehen, operator <<das bei einem bestimmten Zeichentyp gedruckt wird.

Geschichtenerzähler - Unslander Monica
quelle
18

Nur um einen Verweis auf die bereits gegebenen Antworten hinzuzufügen. Aus dem CPP-Standardarbeitsentwurf N4713 :

8.5.2.1 Unäre Operatoren
...

  1. Der Operand des Operators unary + muss eine arithmetische, nicht skalierte Aufzählung oder einen Zeigertyp haben, und das Ergebnis ist der Wert des Arguments. Die integrale Heraufstufung wird für Integral- oder Aufzählungsoperanden durchgeführt. Der Typ des Ergebnisses ist der Typ des heraufgestuften Operanden.

Und char, short, int, und longsind integrale Typen.

PW
quelle
12

Ohne +das Ergebnis wird es anders sein. Die folgenden Snippet-Ausgaben a 97statta a

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

Der Grund dafür ist, dass unterschiedliche Überladungen unterschiedliche Datentypen drucken . Es gibt keine basic_ostream& operator<<( char value );Überlastung für std::basic_ostreamund es wird am Ende der Seite erklärt

Zeichen- und Zeichenfolgenargumente (z. B. vom Typ charoder const char*) werden von den Nicht-Member-Überladungen von behandelt operator<<. Der Versuch zur Ausgabe eines Zeichens das Element Funktionsaufruf Syntax (zB std::cout.operator<<('c');) wird eine von Überlastungen nennen (2-4) und dem Ausgang der Zahlenwert . Wenn Sie versuchen, eine Zeichenfolge mithilfe der Syntax des Elementfunktionsaufrufs auszugeben, wird overload (7) aufgerufen und stattdessen der Zeigerwert gedruckt.

Die Nichtmitgliedsüberladung , die aufgerufen wird, wenn Sie eine charVariable übergeben, ist

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

Dadurch wird das Zeichen am Codepunkt ausgedruckt ch

Also im Grunde , wenn Sie passieren char, signed charoder unsigned chardirekt in den Stream wird es den Charakter ausdrucken. Wenn Sie versuchen, die +obigen Zeilen zu entfernen, werden Sie feststellen, dass einige "seltsame" oder nicht sichtbare Zeichen gedruckt werden, was nicht den Erwartungen entspricht

Wenn Sie ihre numerische Werte wollen stattdessen müssen Sie die Überlastung für nennen short, int, longoderlong long . Der einfachste Weg, dies zu tun, ist die Förderung von charbis intmit unary plus +. Dies ist eine der seltenen nützlichen Anwendungen des unären Plus-Operators . Eine explizite Besetzung von intwird ebenfalls funktionieren

Es gibt viele Leute, die dieses Problem auf SO mögen

phuclv
quelle
1
Meinten Sie unäres Plus , nicht Minus?
Ruslan