Dalam contoh Stroustrup, apa arti usus besar dalam “return 1: 2”?

163

Saya tidak mengerti satu penggunaan khusus usus besar.

Saya menemukannya di buku The C ++ Programming Language oleh Bjarne Stroustrup, edisi ke-4, bagian 11.4.4 "Telepon dan Kembali", halaman 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
}

Usus besar yang membingungkan muncul di baris 7, dalam pernyataan return 1 : 2 . Saya tidak tahu apa itu. Ini bukan label atau operator ternary.

Sepertinya operator ternary kondisional tanpa anggota pertama (dan tanpa ?), tetapi dalam kasus itu saya tidak mengerti bagaimana itu bisa bekerja tanpa syarat.

Piockñec
sumber
6
Ini kesalahan kompilasi di pihak saya (gcc dan dentang). Ditambah semua garis itu membutuhkan titik koma, tetapi masih merupakan kesalahan.
Cruz Jean
216
Moderator Catatan: Harap pikirkan dengan sangat hati-hati sebelum memberikan suara untuk menutup ini sebagai pertanyaan "salah ketik". Ya, masalahnya adalah kesalahan ketik, tapi itu bukan kesalahan ketik yang dibuat oleh penanya. Sebaliknya, itu ditemukan dalam buku yang diterbitkan. Itu berarti pertanyaan ini dan jawabannya mungkin berguna bagi orang lain di masa depan, yang merupakan indikator tandingan yang kuat untuk menutupnya sebagai salah ketik. (PEMBARUAN: Topik ini sekarang sedang dibahas di Meta ; silakan menimbang di sana.)
Cody Gray
3
Mungkin jawaban terbaik adalah: Cobalah untuk mengkompilasi kode; jika tidak dikompilasi, itu indikasi yang baik bahwa itu salah ketik.
jrw32982 mendukung Monica
Saya dapat memikirkan sejumlah contoh dari atas kepala saya yang gagal dikompilasi (atau bahkan menyebabkan kesalahan kompiler internal) pada satu kompiler, tetapi diterima tanpa masalah pada yang berbeda
J. Antonio Perez
1
@ John Saya baru saja mencoba beberapa ekspresi lipat dengan MSVC dan mereka tidak mengkompilasi. Jadi jelas seluruh bab yang baru saja saya baca pasti salah ketik? ;) Kompiler C ++ gagal mengkompilasi kode C ++ yang valid sepanjang waktu, berasal dari bahasa yang sangat rumit.
Voo

Jawaban:

205

Ini salah ketik dalam buku ini. Lihatlah Errata untuk cetakan 2 dan 3 Bahasa Pemrograman C ++ . Contohnya harus seperti di bawah ini:

auto z3 =[y]() { return (y) ? 1 : 2; }
SM
sumber
11
Kenapa (y)dan tidak adil y?
Little Helper
7
@LittleHelper Mungkin ini praktik terbaik atau sesuatu, saya selalu melihatnya ditulis seperti itu. Mungkin untuk menghindari kebingungan dengan perbandingan yang lebih rumit ...
Program Redwolf
28
Secara pribadi, saya sering menggunakan (cond) ? a : buntuk kejelasan - itu membantu saya menghindari salah membaca misalnya pernyataan foo = x > y ? a : bseperti foo = x ...ketika membaca sekilas melalui kode.
user1686
8
@LittleHelper Tidak terlalu dibutuhkan di sana. Namun dalam makro seperti fungsi, praktik terbaik untuk menempatkan tanda kurung di sekitar argumen di mana mereka digunakan, karena jika tidak ekspansi argumen dapat memberikan perilaku yang tidak terduga. Pertimbangkan makro seperti fungsi untuk menggandakan nilai "foo (x) x * 2" di mana Anda menyebutnya dengan "foo (2 + 3)". Hasilnya akan menjadi 2+ (3 * 2) karena argumen akan diperluas apa adanya dan aturan diutamakan mengambil alih. Jika makro Anda adalah "foo (x) (x) * 2" maka Anda akan mendapatkan (2 + 3) * 2 dengan benar. Mungkin Stroustrup memiliki kebiasaan menggunakan gaya itu di mana-mana untuk keamanan pengkodean.
Graham
2
@ Bahraham Sangat tidak mungkin. Stroustrup pada dasarnya tidak menulis fungsi makro (fungsi C ++ inline lebih baik). Jauh lebih mungkin adalah bahwa operator ternary memiliki aturan presedensi yang agak rumit, jadi ada baiknya mengklarifikasi presedensi dengan parens.
Martin Bonner mendukung Monica
19

Sepertinya saya salah ketik. Mungkin seharusnya:

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

Perhatikan bahwa karena lambda tidak mengambil parameter apa pun, parens adalah opsional. Anda dapat menggunakan ini sebagai gantinya, jika Anda lebih suka:

auto z3 =[y] { return y ? 1 : 2; }
Jerry Coffin
sumber
11

return 1 : 2; adalah kesalahan sintaksis, ini bukan kode yang valid.

return (y) ? 1 : 2;Sebaliknya, pernyataan yang benar akan lebih seperti .

Remy Lebeau
sumber