2013-01-16 16 views
27

L'operatore unario + è incluso solo per simmetria con l'operatore unario - o trova qualche utilizzo pratico nel codice C++?L'operatore unario + ha qualche utilità pratica?

Cercando qui, mi sono imbattuto in What is the purpose of the unary '+' operator in C?, ma gli unici scenari utili in questo caso coinvolgono macro preprocessore. Questi sono buoni a sapersi, ma sembrano essere situazioni meno comuni e coinvolgono macro. Ci sono casi d'uso che riguardano più codice C++?

+6

Matematico? No. Ma potrebbe trovare un uso nell'overloading dell'operatore con le classi. – ApproachingDarknessFish

+0

@ValekHalfHeart: Sì, ma qualsiasi sovraccarico che faccia qualsiasi cosa tranne "return * this;" sarà visto come un abuso. – rodrigo

+0

@rodrigo Ma potrebbe ancora fornire un effetto collaterale su "questo", vero? Se questo è buono o utile, il design DSL è un'altra domanda. –

risposta

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

Il primo inserimento scrive il carattere a a cout. Il secondo inserimento scrive il valore numerico di ch a cout. Ma è un po 'oscuro; si basa sul compilatore che applica le promozioni integrali per l'operatore +.

+12

Oohh ... è * eccentrico * –

+0

Il valore numerico è equivalente ASCII? – 0x499602D2

+1

@David - con un compilatore che usa ASCII, sì. Per altre codifiche (rare), no. –

21

La simmetria con unario - non è del tutto inutile; esso può essere utilizzato per evidenziare:

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

E un sovraccarico unario + può essere utilizzato per indicare un'operazione che produce lo stesso logica valore come operando, durante l'esecuzione di un certo calcolo non banale. (Ho visto questo fatto per le conversioni di tipo in Ada, che consente un sovraccarico di + univoco, ma non di conversioni.) Non ho un buon esempio di C++ da portare a mano, e si potrebbe obiettare che sarebbe un cattivo stile. (Poi di nuovo, ho visto un sacco di declamazioni circa sovraccarico <<.)

Per quanto riguarda il motivo per cui C++ ha, è probabilmente in gran parte per la coerenza con la C, che ha aggiunto con lo standard ANSI 1989. Il C Rationale dice semplicemente:

più unario è stata adottata dal Comitato C89 da diversi implementazioni, per simmetria con meno unario.

+3

+1 Una bella citazione. – sehe

10

Se esplicitamente rimanere chiaro di qualsiasi semantica di valore numero per una classe, qualsiasi l'overloading degli operatori è chiaro di non "fare come i int fanno". In tal caso, il più unario può ottenere qualsiasi significato, facendo molto di più di un semplice ritorno *this

esempio importante: Boost.Spirit's unary plus per la incorporato EBNF del Kleene Plus genera una regola parser che permette si tratta di argomento (una regola parser pure) partita uno o più volte.

+1

Vorrei poter sovraccaricare anche '@', '$' e '#. –

+0

@MooingDuck E mentre ci sei, possiamo avere la possibilità di creare i nostri operatori, da qualsiasi combinazione di '+ - * /% =! <> ~^| & *. []() @ # $ '? –

+0

La maggior parte di questi renderebbe l'analisi ambigua. Se il compilatore vede 'a + -b', è il builtin o un sovraccarico dell'utente? –

1

Unario + applica promozioni integrali. @ La risposta di PeteBecker mostra un modo che può essere utile.

Per un altro, si noti che un tipo di enumerazione senza ambito viene promosso a un tipo intero che può rappresentare tutti i valori nello enum. Quindi, in C++ 03, anche in assenza di C++ 11 di std::underlying_type<T>, si potrebbe fare:

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

Il + operatore unario trasforma un lvalue in un rvalue:

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

// ... 

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

noes Oh! Questo codice non collegherà, perché qualcuno ha dimenticato di definire (oltre a dichiarare) A::value.std::min prende i suoi argomenti per riferimento in modo A::value deve avere un indirizzo in modo un riferimento può legarsi ad esso (tecnicamente, quella regola definizione dice che deve essere definito esattamente una volta nel programma.)

Nevermind, più unario in soccorso:

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

il plus unario crea una temporanea con lo stesso valore, e il riferimento si lega alla temporanea, in modo che possiamo risolvere la definizione mancante.

Questo non è qualcosa che è necessario spesso, ma è un uso pratico dell'operatore più unario.

1

Un po 'in ritardo, ma ecco un uso molto contorto che ho trovato. Apparentemente l'operatore + può essere utile (se forse non strettamente necessario) quando si progettano misure di sicurezza attorno alla possibilità di incontrare token di preprocessore vuoti. Vedi this post per una discussione più approfondita.

È pratico, ma per niente piacevole.

Problemi correlati