Domanda

Che cosa fa l'operatore più unario fare? Esistono diverse definizioni che ho trovato ( qui e qui ) ma ho ancora idea di cosa potrebbe essere utilizzato per. Sembra che non fare nulla, ma ci deve essere una ragione per questo, giusto?

È stato utile?

Soluzione

E 'lì per essere sovraccaricato se si sente il bisogno; per tutti i tipi predefiniti è essenzialmente un no-op.

Gli usi pratici di un no-op operatore aritmetico unario sono piuttosto limitate, e tendono a riguardare le conseguenze dell'utilizzo di un valore in un'espressione aritmetica, piuttosto che l'operatore stesso. Ad esempio, può essere usato per forzare ampliamento da tipi integrali piccole per int, o garantiscono un tale risultato di un'espressione viene trattato come un rvalue e quindi non compatibile con un parametro di riferimento non const. A mio avviso, tuttavia, che questi usi sono più adatti al golf il codice di leggibilità. : -)

Altri suggerimenti

In realtà, unario più fa fare qualcosa - anche in C. Si esegue la solito aritmetica conversioni sulla operando e restituisce un nuovo valore, che può essere un numero intero maggiore larghezza. Se il valore originale era un intero senza segno di larghezza minore rispetto int, sarà modificato in un valore signed pure.

Di solito questo non è così importante, ma possono hanno un effetto, quindi è non una buona idea usare unario più come una sorta di "commento" che denota che un numero intero positivo. Si consideri il seguente programma C ++:

void foo(unsigned short x)
{
 std::cout << "x is an unsigned short" << std::endl;
}

void foo(int x)
{
 std::cout << "x is an int" << std::endl;
}

int main()
{
 unsigned short x = 5;
 foo(+x);
}

Questo mostrerà "x è un int".

Quindi in questo esempio unario più creato un nuovo valore con un diverso tipo e signedness.

Da K & R seconda edizione:

  

Il unario + è nuovo con lo standard ANSI. E 'stato aggiunto per simmetria con l'unario -.

L'ho visto usato per chiarezza, per sottolineare il valore positivo in quanto distinto da un valore negativo:

shift(+1);
shift(-1);

Ma questo è un uso piuttosto debole. La risposta è decisamente sovraccarico.

Una cosa che il + unario built-in non si sta trasformando in un lvalue rvalue. Ad esempio, si può fare questo

int x;
&x;

, ma non si può fare questo

&+x;

:)

P.S. "Sovraccarico" non è sicuramente la risposta giusta. + Unario è stato ereditato da C e non c'è nessun operatore a livello utente sovraccarico in C.

La cosa principale unario + compie è tipo di promozione per un int per i tipi di dati più piccoli-che-int. Questo può essere molto utile se si sta cercando di stampare i dati char utilizzando std::cout come dati numerici.

char x = 5;
std::cout << +x << "\n";

è molto diverso da

char x=5;
std::cout << x << "\n";

E 'disponibile anche per sovraccarico, ma in pratica il vostro sovraccarico di dovrebbe essere quasi un NOP.

Se hai bisogno di stampare il valore numerico di byte prime (ad esempio, piccoli numeri memorizzati come char) per eseguire il debug o qualsiasi motivo, unario + può semplificare il codice di stampa. Considerare

char c = 42;
cout << c << endl;           // prints "*\n", not what you want in this case
cout << (int)c << endl;      // prints "42\n", ok
cout << +c << endl;          // prints "42\n", much easier to type

Questo è solo un esempio veloce. Sono sicuro che ci sono altri momenti in cui unario + può aiutare a trattare i byte più come numeri invece di testo come.

Un bocconcino storica. Il comitato di normalizzazione C99 anche pensato impieghi attuali dei unario più erano abbastanza rare, come dimostra la loro considerazione riutilizzarlo per raggiungere un altro elemento nel linguaggio: l'inibizione della valutazione traduzione in tempo di floating-point espressioni costanti. Vedere il seguente citazione dal C Razionale, sezione F.7.4:

  

Una prima versione di questa specifica ha permesso di traduzione in tempo costante l'aritmetica, ma   abilitata l'operatore unario +, quando applicato ad un operando, per inibire Traduzione tempo   valutazione di espressioni costanti.

Alla fine, la semantica fossero invertite, con la valutazione in fase di esecuzione forzata nella maggior parte dei contesti (almeno fino al "come se" regola), e la capacità di far rispettare la valutazione di traduzione in tempo con l'uso di inizializzatori statici. Si noti che la differenza principale risiede nella presenza di floating point eccezioni, e altri punto di arrotondamento o precisione impostazioni galleggianti, ove presenti.

Non molto. L'argomento generale per consentire il sovraccarico di operator+() è che ci sono mondo sicuramente reale utilizza per sovraccarico operator-(), e sarebbe molto strano (o asimmetrica) se si dovesse consentire sovraccarico operator-() ma non operator+().

Credo che ho letto questo argomento da Stroustrop, ma io non ho i miei libri con me giusto per verificarla. Potrei sbagliarmi.

Più unario era presente in C, dove ha fatto assolutamente nulla (proprio come la parola auto). Al fine di non averlo, Stroustrup avrebbe dovuto introdurre un'incompatibilità gratuita con C.

Una volta era in C ++, è stato naturale per consentire una funzione di sovraccarico, proprio come meno unario, e Stroustrup avrebbe introdotto per questo motivo, se non era già lì.

Quindi, non significa niente. Può essere utilizzato come come una sorta di decorazione per rendere le cose sembrano più simmetrico, utilizzando 1,5 come l'opposto a -1,5 per esempio. In C ++, può essere sovraccaricato, ma che sta per essere fonte di confusione se operator+() fa niente. Ricordate la regola standard:. Quando il sovraccarico operatori aritmetici, fare le cose come le fanno ints

Se siete alla ricerca di un motivo per cui è lì, trovare qualcosa circa la storia antica di C. Ho il sospetto che non vi era alcuna buona ragione, come C non è mai stato progettato. Si consideri la parola auto inutile (presumibilmente in contrasto static, ora riciclati in C ++ 0x), e la parola chiave entry, che non ha nulla (e successivamente omessa in C90). C'è un famoso e-mail in cui Ritchie o Kernighan dicono che, quando hanno realizzato la precedenza operatore ha avuto problemi, ci sono stati già tre installazioni con migliaia di righe di codice che non volevano rompere.

Non posso citare alcuna fonte per questo, ma sono venuto a capire che è per il tipo di promozione esplicita, il che implica la conversione di tipo lossless. Che mette in cima alla gerarchia di conversione,

  • Promozione: new_type operator+(old_type)
  • Conversione: new_type(old_type)
  • Cast: operator(new_type)(old_type)
  • La coercizione: new_type operator=(old_type)

Naturalmente, questo è dalla mia interpretazione di una nota in uno dei Microsoft (molto vecchi) C / C ++ manuali che ho letto circa 15 anni fa, in modo da prendere con un grano di sale.

#include <stdio.h>
int main()
{
    unsigned short x = 5;
    printf ("%d\n",sizeof(+x)); 
    printf ("%d\n",sizeof(x)); 
    return 0;
}

Come illustrato nell'esempio precedente, il unario + cambia proprio il tipo, dimensione 4 e 2, rispettivamente. Strano che l'espressione + x è infatti calcolato nel sizeof, ho pensato che non avrei dovuto. Forse è dovuto al fatto che sizeof ha la stessa priorità del unario +.

suppongo che si possa usare per fare sempre un numero positivo. Basta sovraccaricare l'operatore unario + per essere abs. Non vale veramente la pena di confondere i tuoi colleghi sviluppatori, a meno che realmente desidera solo per offuscare il codice. Poi in questo modo funziona bene.

Modifica Riscritto completamente, perché ero waaaayyy fuori nella mia risposta originale.

Ciò dovrebbe consentire di gestire l'esplicita dichiarazione del tipo come un valore positivo (credo nelle operazioni per lo più non-matematici). Sembra che la negazione sarebbe più utile, ma credo che qui un esempio di dove potrebbe fare la differenza:

public struct Acceleration
{
    private readonly decimal rate;
    private readonly Vector vector;

    public Acceleration(decimal rate, Vector vector)
    {
        this.vector = vector;
        this.rate = rate;
    }

    public static Acceleration operator +(Acceleration other)
    {
        if (other.Vector.Z >= 0)
        {
            return other;
        }
        return new Acceleration(other.Rate, new Vector(other.vector.X, other.Vector.Y, -other.vector.Z));
    }

    public static Acceleration operator -(Acceleration other)
    {
        if (other.Vector.Z <= 0)
        {
            return other;
        }
        return new Acceleration(other.Rate, new Vector(other.vector.X, other.Vector.Y, -other.vector.Z));
    }

    public decimal Rate
    {
        get { return rate; }
    }

    public Vector Vector
    {
        get { return vector; }
    }
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top