Domanda

[Questa domanda è collegata ma non uguale a questo .]

Se provo a usare valori di determinati tipi come espressioni booleane, ricevo un avviso. Invece di sopprimere l'avviso, a volte uso l'operatore ternario (? ) per convertire in bool. L'uso di due non operatori ( !! ) sembra fare la stessa cosa.

Ecco cosa intendo:

typedef long T;       // similar warning with void * or double
T t = 0;
bool b = t;           // performance warning: forcing 'long' value to 'bool'
b = t ? true : false; // ok
b = !!t;              // any different?

Quindi, la tecnica del doppio non fa davvero la stessa cosa? È più o meno sicuro della tecnica ternaria? Questa tecnica è ugualmente sicura con tipi non integrali (ad es. Con void * o double per T )?

Non sto chiedendo se !! t sia di buon stile. Sto chiedendo se è semanticamente diverso da t? true: false .

È stato utile?

Soluzione

L'argomento del! operatore e il primo argomento dell'operatore ternario sono entrambi implicitamente convertiti in bool, quindi !! e?: sono le decorazioni ridondanti sciocche dell'IMO del cast. Voto per

b = (t != 0);

Nessuna conversione implicita.

Altri suggerimenti

In alternativa, puoi farlo: bool b = (t! = 0)

Attenzione!

  • Un booleano riguarda verità e falsità.
  • Un numero intero riguarda numeri interi.

Questi sono concetti molto distinti:

  • La verità e la falsità riguardano il decidere cose.
  • I numeri riguardano il conteggio delle cose.

Quando si collegano questi concetti, dovrebbe essere fatto esplicitamente. Mi piace di più la versione di Dima:

b = (t! = 0);

Questo codice dice chiaramente: confronta due numeri e memorizza il valore di verità in un valore booleano.

Tutte le tecniche valide, tutte genereranno lo stesso codice.

Personalmente, disabilito solo l'avviso in modo da poter usare la sintassi più pulita. Fare il bool non è qualcosa che mi preoccupa di fare accidentalmente.


Sì, è sicuro.


0 viene interpretato come falso, tutto il resto è vero,
quindi! 5 viene fuori come falso
! 0 viene visualizzato come vero
così !! 5 risulta vero

Non vorrei usare:

bool b = !!t;

Questo è il modo meno leggibile (e quindi il più difficile da mantenere)

Gli altri dipendono dalla situazione.
Se stai convertendo per usare solo un'espressione bool.

bool b = t ? true : false;
if (b)
{
    doSomething();
}

Quindi vorrei lasciare che la lingua lo facesse per te:

if (t)
{
    doSomething();
}

Se stai effettivamente memorizzando un valore booleano. Quindi prima mi chiedo perché hai un lungo periodo nei primi posti che richiede il cast. Supponendo che abbiate bisogno del valore long e bool, prenderei in considerazione tutto quanto segue a seconda della situazione.

bool  b = t ? true : false;      // Short and too the point.
                                 // But not everybody groks this especially beginners.
bool  b = (t != 0);              // Gives the exact meaning of what you want to do.
bool  b = static_cast<bool>(t);  // Implies that t has no semantic meaning
                                 // except as a bool in this context.

Sommario: Usa ciò che fornisce il maggior significato per il contesto in cui ti trovi.
Cerca di rendere ovvio ciò che stai facendo

Consiglio di non sopprimere mai quell'avvertimento e di non usare mai un cast (bool) per sopprimerlo. Le conversioni potrebbero non essere sempre chiamate come si presume.

C'è una differenza tra un'espressione che restituisce vero e un valore booleano di quel valore.

Entrambi !! e ternario ci si abitua, ma farà il lavoro in modo simile, se non si desidera definire tipi interni con cast sovraccarichi da booleare.

Anche l'approccio di Dima va bene, poiché assegna il valore di un'espressione a un bool.

Se sei preoccupato per l'avvertimento, puoi anche forzare il cast: bool b = (bool) t;

Odio davvero !! t !!!!!!. Presenta la cosa peggiore di C e C ++, la tentazione di essere troppo intelligente della metà con la tua sintassi.

bool b (t! = 0); // È il modo migliore per IMHO, mostra esplicitamente cosa sta succedendo.

!! può essere compatto, ma penso che sia inutilmente complicato. Meglio disabilitare l'avvertimento o usare l'operatore ternario, secondo me.

Vorrei usare b = (0! = t) - almeno qualsiasi persona sana di mente può leggerlo facilmente. Se vedessi un doppio pericolo nel codice, sarei piuttosto sorpreso.

Disabilita l'avviso.

Scrivi prima per chiarezza; quindi profilo; quindi ottimizzare per la velocità, dove richiesto.

!! è utile solo quando usi un'espressione booleana in modo aritmetico, ad esempio:

c = 3 + !!extra; //3 or 4

(Il cui stile è una discussione diversa.) Quando tutto ciò che serve è un'espressione booleana, il !! è ridondante. Scrivendo

bool b = !!extra;

ha tanto senso quanto:

if (!!extra) { ... }

Il confronto con 0 non funziona così bene. Che ritorna - perché !! contro ternario?

class foo { public: explicit operator bool () ; };

foo f;

auto a = f != 0; // invalid operands to binary expression ('foo' and 'int')
auto b = f ? true : false; // ok
auto c = !!f; // ok

Consiglio di usare

if (x! = 0)

o

if (x! = NULL)

invece di if (x); è più comprensibile e leggibile.

Il doppio non mi sembra divertente e nel codice di debug sarà molto diverso rispetto al codice ottimizzato.

Se sei innamorato di !! potresti sempre Macro.

#define LONGTOBOOL(x) (!!(x))

(a parte questo, l'operatore ternario è ciò che preferisco in questi casi)

Vorrei usare bool b = t e lasciare l'avviso di compilazione, commentando la sicurezza di questa particolare riga. Disabilitare l'avviso può morderti nel culo in un'altra parte del codice.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top