Cosa fa l’operatore virgola?

Cosa fa il seguente codice in C / C ++?

if (blah(), 5) { //do something } 

L’operatore virgola viene applicato e il valore 5 viene utilizzato per determinare il condizionale vero / falso.

Eseguirà blah () e otterrà qualcosa indietro (presumibilmente), quindi viene utilizzato l’operatore virgola e 5 sarà l’unica cosa che viene utilizzata per determinare il valore vero / falso per l’espressione.


Si noti che l’operatore, potrebbe essere sovraccaricato per il tipo di ritorno della funzione blah () (che non è stata specificata), rendendo il risultato non ovvio.

Se l’operatore virgola non è sovraccarico, il codice è simile a questo:

 blah(); if (5) { // do something } 

Se l’operatore virgola è sovraccarico, il risultato sarà basato su quella funzione.

 #include  #include  using namespace std; string blah() { return "blah"; } bool operator,(const string& key, const int& val) { return false; } int main (int argc, char * const argv[]) { if (blah(), 5) { cout << "if block"; } else { cout << "else block"; } return 0; } 

(modificato per mostrare lo scenario di sovraccarico operatore virgola. grazie a David Pierre per aver commentato questo)

So una cosa che questo tipo di codice dovrebbe fare: dovrebbe far sparare il programmatore. Sarei un po ‘spaventato a lavorare accanto a qualcuno che scrive così.

Nel caso patologico, dipende da cosa fa l’operatore virgola …

 class PlaceHolder { }; PlaceHolder Blah() { return PlaceHolder(); } bool operator,(PlaceHolder, int) { return false; } if (Blah(), 5) { cout << "This will never run."; } 

Direi che dipende da blah ().

Su una risposta più ampia L’operatore virgola (non sovraccarico) risolve come in, esegue la prima parte e restituisce la seconda parte.

Quindi se hai (foo (), bar ()) entrambe le funzioni verranno eseguite, ma il valore dell’espressione viene valutato su bar () (e anche il tipo di espressione).

Mentre non dirò che ci sono usi giusti per questo, di solito è considerato un po ‘difficile da leggere il codice. Principalmente perché non molte lingue condividono tali costrutti. Quindi come regola empirica lo evito a meno che non aggiungo codice a un’espressione preesistente e non voglia modificare completamente il suo formato.

Esempio: ho una macro (non discutendo se dovresti usare macro o no, a volte non è nemmeno tu che l’hai scritta)

FIND_SOMETHING (X) (x> 2)? find_fruits (x): find_houses (x)

E di solito lo uso in compiti come my_possession = FIND_SOMETHING (34);

Ora voglio aggiungere il registro ad esso per scopi debuggin, ma non posso cambiare le funzioni di ricerca ,. Potrei fare :

FIND_SOMETHING (X) (x> 2)? (LOG (“ricerca di frutta”), find_fruits (x)) 🙁 LOG (“ricerca di case”), find_houses (x))

Uso talvolta costrutti come questo per scopi di debug. Quando costringo il se vicino ad essere vero indipendentemente dal valore di ritorno di blah. È ovvio che non dovrebbe mai apparire nel codice di produzione.

Quanto segue è stato scritto supponendo che si tratti di codice C, in un file C o all’interno di un blocco C di un file C ++:

È inutile se . Chiamerà blah (), tuttavia il risultato di blah () non viene considerato da affatto. L’unica cosa che viene considerata è 5, quindi il se valuterà sempre il vero. IOW potresti scrivere questo codice come

 blah(); // do something 

senza nessuno se non del tutto.