Confronto tra una variabile e un intervallo di valori

In matematica, la notazione 18 < age < 30 indica che l’età deve essere compresa tra i valori 18 e 30. È ansible utilizzare questo tipo di notazione nella dichiarazione if? Ad esempio, ho provato ad eseguire

 if(18 < age < 30) 

e ottengo risultati strani, quindi non è giusto. C’è un modo per fare questo o così semplicemente devo scrivere

 if(age > 18) /*blah*/; else if(age < 30) /*same blah*/; 

Tu puoi fare:

 if (18 < age && age < 30) /*blah*/; 

Nessuno ha risposto a cosa è successo esattamente con il tuo codice, quindi lasciami a parte.

Considera la singola affermazione: bool result = 18 < age < 30;

Vogliamo valutare l'espressione della mano destra: 18 < age < 30

Ci sono due operatori in questa espressione e, poiché sono identici, hanno entrambi la stessa priorità, in questo caso vengono valutati da sinistra a destra, quindi l'espressione è equivalente a:

 (18 < age) < 30 

Quindi esaminiamo prima il membro della mano sinistra: 18 < age , produce un valore booleano che è vero o falso, tipicamente rappresentato come un valore integrale rispettivamente 1 o 0. Quindi l'espressione può essere riassunta come:

 {0,1} < 30 

che è sempre vero

Pertanto, dovresti usare assert(18 < age < 30); non si sarebbe mai ritorto contro.

Questa conversione implicita tra tipi built-in interi (e floating point) è davvero fastidiosa ...

Un po ‘di codice template può aiutare qui:

 template  class range { static bool contains(int i) { return min <= i && i < max; } // In C++, ranges usually are half-open. }; int age = 23; if (range<18,30>::contains(age)) { /****/ } 

È ansible utilizzare questo tipo di notazione nella dichiarazione if?

Sì, ansible.

Auspicabile, quasi mai: i programmatori presumono che i comportamenti descritti in altre risposte si applicheranno sempre, quindi se cambi drasticamente l’ordine di valutazione e il significato di un’espressione, allora li confonderà molto male e – prima o poi – causerà dolore. Se hai un progetto molto piccolo con pochi membri dello staff, in pratica cercano di creare un linguaggio specifico del dominio in C ++, dove la notazione del dominio è molto più leggibile e familiare usando questa notazione (forse sono matematici, non programmatori in ogni caso ), quindi in extremis potresti considerare qualcosa di simile al presente di seguito, anche se è ancora probabile che causi problemi.

Ho implementato questo genere di cose prima di anni fa come esercizio esplorativo. Se desideri farlo ma hai bisogno di aiuto per iniziare: in cima alla mia testa (cioè senza dubbio buggy), considera:

 struct Weird { Weird(int n) : n_(n), b_is_meaningful_(false) { } Weird(int n, bool b) : n_(n), b_is_meaningful_(true), b_(b) { } int n_; bool b_is_meaningful_; bool b_; }; Weird operator<(Weird lhs, Weird rhs) { if (lhs.b_is_meaningful_) if (!lhs.b_) // effectively, anding with something already known false... return Weird(rhs.n_, false); return Weird(rhs.n_, lhs.n_ < rhs.n_); } 

Fondamentalmente, lo fai girare fino a quando puoi:

 Weird x = 10; assert(6 < x < 20 < 30 < Weird(80)); 

In ogni punto, l' operator< crea un nuovo object Weird con il valore Rights Side (rhs), mentre aggiorna lo stato booleano partendo dal presupposto che si sta effettivamente lavorando insieme un insieme di confronti. Se vuoi davvero fare un casino, puoi supportare tutti i tipi di cose in C ++, potresti avere una crepa a dire "x == 6 || 3 || 56" per divertimento ...?

Non conosco il modo di fare esattamente come chiedi, ma il modo normale è

Utilizzare l’operatore e

se (età> 18 anni e età <30 anni)

Oppure scriviti un bel set di funzioni che fa questo

 template  bool in_range_[none|both|low|high]( value, min, max ) 

per soddisfare tutti i tipi di confini inclusi / o non

(non usare questo per virgola mobile)

In C ++ 0x puoi consentire e disabilitare tutte le altre possibilità usando la parola chiave “cancella” che disabilita le funzioni per sovraccarichi come

Puoi scrivere un’espressione booleana come

 ((18 < age) && (age < 30)) 

Un'espressione come quella sopra può essere usata ovunque sia accettabile un'espressione booleana, ad esempio (ma non solo):

 if((18 < age) && (age < 30)) { ... } 

o

 bool age_in_range = ((18 < age) && (age < 30)); 

Si noti che l'espressione di cui sopra utilizza la valutazione di cortocircuito operator && .