2013-01-16 8 views
27

War der unäre Operator + nur für die Symmetrie mit dem unären Operator - enthalten, oder findet er eine praktische Verwendung in C++ - Code?Hat der unary + Operator einen praktischen Nutzen?

Bei der Suche hier bin ich auf What is the purpose of the unary '+' operator in C? gestoßen, aber die einzigen nützlichen Szenarios sind Präprozessor-Makros. Das ist gut zu wissen, aber sie scheinen einige weniger häufige Situationen zu sein und beinhalten Makros. Gibt es Anwendungsfälle mit häufigerem C++ - Code?

+6

Mathematisch? Nein. Aber es könnte eine Verwendung beim Überladen von Operatoren mit Klassen finden. – ApproachingDarknessFish

+0

@ValekHalfHeart: Ja, aber jede Überlastung, die irgendetwas anderes als "Rückkehr" bewirkt, wird als Missbrauch angesehen. – rodrigo

+0

@rodrigo Aber könnte noch eine Nebenwirkung auf "this", nicht wahr? Ob das gut oder nützlich ist DSL-Design ist eine andere Frage. –

Antwort

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

Die erste Einbringungs schreibt das Zeichen a zu cout. Die zweite Einfügung schreibt den numerischen Wert ch in cout. Aber das ist ein bisschen unklar; Es beruht auf dem Compiler, der integrale Aktionen für den Operator + anwendet.

+12

Oohh ... das ist * kinky * –

+0

Ist der numerische Wert sein ASCII-Äquivalent? – 0x499602D2

+1

@David - mit einem Compiler, der ASCII verwendet, ja. Für andere Kodierungen (selten), nein. –

21

Symmetrie mit unären - ist nicht völlig nutzlos;

const int foo = -1; 
const int bar = +1; 

Und ein unären + kann eine Operation zur Bezeichnung verwendet werden, überlastet, die die gleiche logische Wert als Operand ergibt, während einige nicht-triviale Berechnung durchführen: es kann für Hervorhebungen verwendet werden. (Ich habe gesehen, dass dies für Typkonvertierungen in Ada getan wurde, wodurch unäre +, aber keine Konvertierungen, überlastet werden können.) Ich habe kein gutes C++ - Beispiel zur Hand, und man könnte argumentieren, dass es ein schlechter Stil wäre. (Dann wieder habe ich viel Erfreuliches gesehen << zu überlasten.)

Was warum C++ hat, ist es wahrscheinlich weitgehend auf Konsistenz mit C, die es mit dem 1989 ANSI-Standard hinzugefügt. Die C Rationale sagt nur:

Unäres Plus wurde aus mehreren Implementierungen vom C89 Ausschuss angenommen wurde, für Symmetrie mit unären Minus.

+3

+1 Ein schönes Zitat. – sehe

10

Wenn Sie frei von jeder Zahlenwert Semantik für eine Klasse, jede Betreiber Überlastung ist ausdrücklich klar bleiben nicht zu „tun, wie die Ints tun“. In diesem Fall können die unären Plus einen Sinn bekommen, tun viel mehr als nur *this

prominentes Beispiel der Rückkehr: Boost.Spirit's unary plus für den Embedded-EBNF des Kleene Plus erzeugt eine Parser-Regel, die läßt Spiel ein, es ist Argument (wie auch eine Parser-Regel) oder mehrere Male.

+1

Ich wünschte, wir könnten auch '@', '$' und '#' überladen. –

+0

@MooingDuck Und wenn Sie schon dabei sind, können wir unsere eigenen Operatoren aus jeder Kombination von '+ - * /% =! <> ~^| & *. []() @ # $ Erstellen '? –

+0

Die meisten davon würden das Parsing mehrdeutig machen. Wenn der Compiler "a + -b" sieht, ist das die eingebaute oder eine Benutzerüberlastung? –

1

Unary + wendet integrierte Werbeaktionen an. @ PeteBeckers Antwort zeigt eine Möglichkeit, die nützlich sein kann.

Zum anderen, beachten Sie, dass ein nicht gekapselter Aufzählungstyp zu einem Integer-Typ hochgestuft wird, der alle Werte in enum darstellen kann. So in C++ 03, auch ohne C++ 11 die std::underlying_type<T>, könnten Sie tun:

enum MyBitMask { 
    Flag1 = 0x1, 
    Flag2 = 0x2, 
    Flag3 = 0x4, 
    Flag4 = 0x8000000 
}; 

inline MyBitMask operator&(MyBitMask x, MyBitMask y) { 
    return static_cast<MyBitMask>(+x & +y); 
} 

inline MyBitMask operator|(MyBitMask x, MyBitMask y) { 
    return static_cast<MyBitMask>(+x | +y); 
} 
4

Die unäre + Betreiber einen L-Wert in einen R-Wert verwandelt:

struct A { 
    static const int value = 1; 
}; 

// ... 

int x = std::min(0, A::value); 

Oh nein! Dieser Code wird nicht verlinkt, weil jemand vergessen hat, A::value zu definieren (und zu deklarieren).std::min nimmt seine Argumente durch Bezugnahme so A::value muss eine Adresse haben, so ein Verweis darauf binden kann (technisch gesehen, die eine Definition der Regel heißt es im Programm genau einmal definiert werden müssen.)

Nevermind, unäres Plus zur Rettung:

int x = std::min(0, +A::value); 

der unäre Plus schafft eine temporäre mit dem gleichen Wert und die Referenz bindet an das temporäre, also können wir rund um die fehlende Definition arbeiten.

Dies ist nicht oft erforderlich, aber es ist eine praktische Anwendung des unary plus-Operators.

1

Ein bisschen spät, aber hier ist eine sehr verdrehte Verwendung, über die ich stolperte. Offensichtlich kann der Operator + nützlich sein (falls es vielleicht nicht unbedingt notwendig ist), wenn Sicherheitsvorkehrungen um die Möglichkeit herum getroffen werden, leere Präprozessor-Token zu treffen. Eine ausführlichere Diskussion finden Sie unter this post.

Es ist praktisch, aber keineswegs angenehm.

Verwandte Themen