ในตัวอย่างของ Stroustrup เครื่องหมายโคลอนหมายถึงอะไรใน“ return 1: 2”?


163

ฉันไม่เข้าใจการใช้โคลอนหนึ่งครั้ง

ฉันพบมันในหนังสือภาษา C ++ Programming Languageโดย Bjarne Stroustrup, 4th edition, ส่วน 11.4.4 "การโทรและส่งคืน", หน้า 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
}

ลำไส้ใหญ่สับสนปรากฏบนเส้น 7 return 1 : 2ในคำสั่ง ฉันไม่รู้ว่ามันจะเป็นอะไร มันไม่ได้เป็นผู้ประกอบการฉลากหรือประกอบไปด้วย

ดูเหมือนว่าผู้ประกอบการที่มีเงื่อนไขโดยไม่มีสมาชิกคนแรก (และไม่มี?) แต่ในกรณีนั้นฉันไม่เข้าใจว่ามันจะทำงานได้อย่างไรโดยไม่มีเงื่อนไข


6
มันเป็นข้อผิดพลาดในการรวบรวมในตอนท้ายของฉัน (gcc และเสียงดังกราว) รวมทุกบรรทัดเหล่านั้นต้องการเครื่องหมายอัฒภาค แต่ก็ยังมีข้อผิดพลาด
Cruz Jean

216
ผู้ดำเนินรายการหมายเหตุ:โปรดไตร่ตรองอย่างรอบคอบก่อนลงคะแนนเพื่อปิดคำถามนี้เป็นคำถาม "พิมพ์ผิด" ใช่ปัญหาเป็นตัวพิมพ์ผิด แต่ไม่ใช่ตัวพิมพ์ผิดที่ผู้ถามทำ แต่พบได้ในหนังสือที่ตีพิมพ์ นั่นหมายความว่าคำถามนี้และคำตอบอาจเป็นประโยชน์กับผู้อื่นในอนาคตซึ่งเป็นตัวบ่งชี้ที่แข็งแกร่งสำหรับการปิดเป็นตัวพิมพ์ผิด (อัปเดต: หัวข้อนี้กำลังถูกกล่าวถึงใน Metaโปรดอย่าลังเลที่จะชั่งน้ำหนักที่นั่น)
Cody Gray

3
บางทีคำตอบที่ดีที่สุดคือลองรวบรวมรหัส; ถ้ามันไม่ได้รวบรวมนั่นเป็นข้อบ่งชี้ที่ดีว่ามันเป็นตัวพิมพ์ผิด
jrw32982 รองรับโมนิก้า

ฉันสามารถคิดถึงตัวอย่างจำนวนหนึ่งที่อยู่ด้านบนของหัวของฉันที่ไม่สามารถคอมไพล์ (หรือทำให้เกิดข้อผิดพลาดของคอมไพเลอร์ภายใน) ในคอมไพเลอร์หนึ่ง แต่ได้รับการยอมรับโดยไม่มีปัญหากับอีกอันหนึ่ง
J. Antonio Perez

1
@ จอห์นฉันเพิ่งลองนิพจน์พับด้วย MSVC และพวกเขาไม่ได้รวบรวม ชัดเจนทั้งบทที่ฉันเพิ่งอ่านจะต้องเป็นตัวพิมพ์ผิดหรือไม่? ;) คอมไพเลอร์ C ++ ไม่สามารถคอมไพล์รหัส C ++ ที่ถูกต้องได้ตลอดเวลามาจากภาษาที่ซับซ้อนอย่างไร้เหตุผล
Voo

คำตอบ:


205

มันเป็นตัวพิมพ์ผิดในหนังสือ ดูที่คหบดีสำหรับสิ่งพิมพ์ที่ 2 และ 3 ของ C ++ Programming ภาษา ตัวอย่างต้องเป็นดังนี้:

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

11
ทำไม(y)และไม่เพียงy?
ผู้ช่วยตัวเล็ก

7
@ LittleHelper บางทีมันเป็นการปฏิบัติที่ดีที่สุดหรือบางสิ่งบางอย่างฉันมักจะเห็นมันเขียนแบบนั้น อาจหลีกเลี่ยงความสับสนด้วยการเปรียบเทียบที่ซับซ้อนมากขึ้น ...
โปรแกรม Redwolf

28
ส่วนตัวฉันมักจะใช้(cond) ? a : bเพื่อความชัดเจน - มันช่วยให้ฉันหลีกเลี่ยงการอ่านผิดเช่นคำสั่งfoo = x > y ? a : bเช่นfoo = x ...เมื่ออ่านผ่านรหัส
user1686

8
@ LittleHelper มันไม่จำเป็นจริงๆ อย่างไรก็ตามในแมโครที่มีลักษณะคล้ายกับฟังก์ชั่นวิธีที่ดีที่สุดคือการใส่วงเล็บให้ล้อมรอบข้อโต้แย้งที่มีการใช้เพราะมิฉะนั้นการขยายตัวของข้อโต้แย้งอาจทำให้เกิดพฤติกรรมที่ไม่คาดคิด พิจารณามาโครที่มีฟังก์ชั่นเหมือนเป็นสองเท่าของค่า "foo (x) x * 2" ซึ่งคุณเรียกมันด้วย "foo (2 + 3)" ผลลัพธ์จะเป็น 2+ (3 * 2) เนื่องจากอาร์กิวเมนต์ได้รับการขยายตามที่เป็นอยู่และกฎที่มีลำดับความสำคัญได้เข้าครอบครอง หากแมโครของคุณคือ "foo (x) (x) * 2" คุณจะได้รับอย่างถูกต้อง (2 + 3) * 2 อาจเป็นเพราะ Stroustrup มีนิสัยในการใช้รูปแบบนั้นทุกที่เพื่อความปลอดภัยในการเขียนโค้ด
Graham

2
@ Graham ไม่น่าเป็นไปได้มาก Stroustrup ไม่ได้เขียนแมโครฟังก์ชัน (ฟังก์ชั่นอินไลน์ C ++ จะดีกว่า) มีโอกาสมากขึ้นที่ผู้ประกอบการที่ประกอบไปด้วยกฎระเบียบที่ค่อนข้างซับซ้อนมาก่อน
Martin Bonner สนับสนุน Monica

19

ดูเหมือนว่าฉันจะพิมพ์ผิดง่าย น่าจะเป็น:

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

โปรดทราบว่าเนื่องจากแลมบ์ดาไม่ได้ใช้พารามิเตอร์ใด ๆ การ parens จึงเป็นทางเลือก คุณสามารถใช้สิ่งนี้แทนหากคุณต้องการ:

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

11

return 1 : 2; เป็นข้อผิดพลาดทางไวยากรณ์ไม่ใช่รหัสที่ถูกต้อง

คำสั่งที่ถูกต้องจะเป็นเหมือนreturn (y) ? 1 : 2;แทน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.