2008-11-18 11 views
5

per i seguenti:Come si esegue un no-op in C/C++?

(a != b) ? cout<<"not equal" : cout<<"equal"; 

supporre Non mi interessa se è uguale, come posso utilizzare la dichiarazione di cui sopra sostituendo cout<<"equal" con un no-op.

+0

possibile duplicato di [Come faccio a implementare no-op macro (o il modello) in C++?] (Http://stackoverflow.com/questions/1306611/how-do -i-implement-no-op-macro-or-template-in-c) – user

risposta

20

Se è davvero un operatore ternario che non ha bisogno di una seconda azione, l'opzione migliore sarebbe quella di sostituirlo per un caso:

if (a!=b) cout << "not equal"; 

sprigiona un odore molto meno.

+0

Questo non funziona se è usato come espressione. "if" non è un'espressione in C. –

+1

Quindi? L'idea è esattamente evitare di fare quel tipo di espressione brutta in primo luogo. –

1

Questo è un codice molto confuso. Si potrebbe solo scrivere

cond ? cout << "equal" : cout; 

ma non sarà (sarà vero?) Perché hai convenzionale if per questo.

0
if (a!=b) cout<<"not equal"; 
11

semplice: avrei codificare come

if (a != b) 
    cout << "not equal"; 

L'operatore ternario richiede i due risultati essere dello stesso tipo. Così si potrebbe anche essere in grado di cavarsela con

(a != b) ? cout << "not equal" : cout; 

perché l'operatore flusso (< <) restituisce solo il riferimento ostream. Questo è brutto e non necessario, secondo me.

1

Penso che il problema qui sia che l'operatore: ha due ESPRESSIONI come argomenti. Diciamo .. a = x? y: z;

L'espressione per definizione deve avere un valore ... ecco perché non è possibile "saltare".

4

L'unica cosa che manca dalle altre risposte è questa: Non c'è modo, direttamente, di codificare un "noop" in C/C++.

Inoltre, facendo: (a != b) ? : printf("equal\n"); in realtà compila per me (gcc -ansi in gcc 4.2.4).

+0

Questo non è completamente vero. Un blocco vuoto può agire come "no-op". Tuttavia, questa non è una * espressione *. Poiché un'espressione deve essere digitata in C++, non c'è letterale/costante che sia universalmente accettabile come "senza valore". "No-op" non è davvero la parola giusta qui. –

+1

gcc ha un'estensione che consente di tralasciare il termine medio, ma non è legale C o C++. – bames53

0

La sintassi richiede solo un'espressione. Puoi semplicemente andare: (a! = B)? Cout < < "non uguale": 1;

+0

qual è il tipo risultante di tale espressione? Int o Stream? – BCS

+0

non funziona: standard: (C? E1: E2) nel modo seguente: se E1 o E2 ha un tipo non di classe, E1 può essere convertito per corrispondere a E2 se E1 può essere convertito implicitamente nel tipo che l'espressione E2 avrebbe se E2 sono stati convertiti in un valore di (o il tipo che ha, se E2 è un valore di riferimento).) –

4

Di seguito vi ottenere quello che stai cercando, tuttavia, potrebbe non essere chiaro a persone che leggono il codice perché funziona:

(a != b) && (cout << "equal"); 

Personalmente, sono d'accordo con this risposta da Vinko Vrsalovic .

+0

Questo è un trucco interessante, ma per motivi di leggibilità mi raccomando di non usarlo. Inoltre, non dovresti fare affidamento sull'ottimizzazione del compilatore. – ya23

+3

@ ya23, potresti essere più preciso su quale ottimizzazione si basa? Quell'espressione è ben definita in tutti i contesti di ottimizzazione. –

1

Se l'obiettivo del codice è l'operazione di uscita e non la condizione, poi qualcosa di simile potrebbe essere fatto:

cout << (cond ? "not equal" : ""); 

ho il sospetto che non è il caso, però, perché si vuole fare nulla in la clausola "altro".

0

Entrambe le affermazioni di compilazione:

(a != b) ? cout<<"not equal" : NULL; 

(a != b) ? NULL : cout<<"equal"; 
1

In C++ 11 è possibile scrivere (in caso di vuoto):

somecondition ? foo() : [] {}() ; 

Così il NOP è in realtà un lambda vuota. Oltre al vuoto è possibile restituire qualsiasi tipo e valore.

Questo potrebbe sembrare un po 'eccessivo tutto da sé, ma si supponga di avere questo:

somecondition1 ? foo1() : 
somecondition2 ? foo2() : 
somecondition3 ? foo3() : 
       flip_out_because_unhandled_condition() ; 

Ora, se qualcuno aggiunge somecondition4, ma dimentica di includere nel codice di gestione, il software chiamare il flip_out_ .. funzione che causa tutti i tipi di effetti indesiderati. Ma forse la somiglianza4 non ha bisogno di alcuna attenzione particolare, deve solo essere ignorata. Bene, allora si potrebbe scrivere:

somecondition1 ? foo1() : 
somecondition2 ? foo2() : 
somecondition3 ? foo3() : 
somecondition4 ? []{}() : 
       flip_out_because_unhandled_condition() ; 
3

(void)0; è noop. C'è un buon motivo per utilizzare il modulo expr?false:true. Guarda come assert() è implementato.

Quindi nel tuo esempio, utilizzare (a != b) ? (void)0 : cout<<"equal";