Nell'esempio di Stroustrup, cosa significano i due punti in "return 1: 2"?


163

Non capisco un uso particolare dei due punti.

L'ho trovato nel libro Il linguaggio di programmazione C ++ di Bjarne Stroustrup, 4a edizione, sezione 11.4.4 "Chiama e ritorna", pagina 297:

void g(double y)
{
  [&]{ f(y); }                                               // return type is void
  auto z1 = [=](int x){ return x+y; }                        // return type is double
  auto z2 = [=,y]{ if (y) return 1; else return 2; }         // error: body too complicated
                                                             // for return type deduction
  auto z3 =[y]() { return 1 : 2; }                           // return type is int
  auto z4 = [=,y]()−>int { if (y) return 1; else return 2; } // OK: explicit return type
}

I due punti confusi appaiono nella riga 7, nell'istruzione return 1 : 2. Non ho idea di cosa potrebbe essere. Non è un'etichetta o un operatore ternario.

Sembra un operatore ternario condizionale senza il primo membro (e senza il ?), ma in quel caso non capisco come possa funzionare senza una condizione.


6
È un errore di compilazione da parte mia (gcc e clang). Inoltre, tutte quelle righe richiedono punti e virgola, ma comunque un errore.
Cruz Jean,

216
Nota del moderatore: ti preghiamo di pensare molto attentamente prima di esprimere un voto per chiudere questa domanda come "errata". Sì, il problema è un errore di battitura, ma non è un errore di battitura fatto dal richiedente. Piuttosto, si trova in un libro pubblicato. Ciò significa che questa domanda e le sue risposte potrebbero essere utili per gli altri in futuro, il che è un forte controindicatore per chiuderlo come errore di battitura. (AGGIORNAMENTO: Questo argomento è attualmente in discussione su Meta ; sentiti libero di ponderare qui.)
Cody Grey

3
Forse la risposta migliore sarebbe: provare a compilare il codice; se non viene compilato, è una buona indicazione che si tratta di un errore di battitura.
jrw32982 supporta Monica

Mi viene in mente un numero di esempi fuori dalla mia testa che non riescono a compilare (o addirittura causare un errore interno del compilatore) su un compilatore, ma sono accettati senza problemi su uno diverso
J. Antonio Perez,

1
@John Ho appena provato alcune espressioni fold con MSVC e non sono state compilate. Quindi chiaramente l'intero capitolo che ho appena letto deve essere un refuso? ;) I compilatori C ++ non riescono a compilare continuamente codice C ++ valido, deriva dal fatto che il linguaggio è assurdamente complicato.
Voo

Risposte:


205

È un refuso nel libro. Guarda Errata per la 2a e 3a stampa del linguaggio di programmazione C ++ . L'esempio deve essere come di seguito:

auto z3 =[y]() { return (y) ? 1 : 2; }

11
Perché (y)e non solo y?
Little Helper,

7
@LittleHelper Forse è una buona pratica o qualcosa del genere, lo vedo sempre scritto così. Forse per evitare confusione con confronti più complicati ...
Programmi Redwolf

28
Personalmente, lo uso spesso (cond) ? a : bper chiarezza: mi aiuta a evitare di leggere male, ad esempio l'affermazione foo = x > y ? a : bcome foo = x ...quando si scorre il codice.
user1686

8
@LittleHelper Non è davvero necessario lì. Tuttavia, in una macro simile a una funzione, è consigliabile mettere le parentesi attorno agli argomenti in cui vengono utilizzati, poiché altrimenti l'espansione degli argomenti può dare un comportamento imprevisto. Considera una macro simile a una funzione per raddoppiare un valore "pippo (x) x * 2" dove lo chiami con "pippo (2 + 3)". Il risultato sarà 2+ (3 * 2) perché l'argomento viene espanso così com'è e le regole di precedenza prendono il sopravvento. Se la tua macro è "pippo (x) (x) * 2", otterrai correttamente (2 + 3) * 2. Può essere che Stroustrup abbia l'abitudine di usare quello stile ovunque per la sicurezza del codice.
Graham,

2
@Graham Molto improbabile. Stroustrup essenzialmente non scrive macro di funzioni (le funzioni inline C ++ sono migliori). Molto più probabile è che l'operatore ternario abbia regole di precedenza un po 'complicate, quindi è bene chiarire abitualmente la precedenza con i genitori.
Martin Bonner supporta Monica

19

Mi sembra un semplice errore di battitura. Probabilmente dovrebbe essere:

auto z3 =[y]() { return y ? 1 : 2; }

Si noti che poiché lambda non accetta alcun parametro, le parentesi sono opzionali. Puoi invece usarlo, se preferisci:

auto z3 =[y] { return y ? 1 : 2; }

11

return 1 : 2; è un errore di sintassi, non è un codice valido.

Una dichiarazione corretta sarebbe invece più simile return (y) ? 1 : 2;.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.