ทำไมโอเปอเรเตอร์! = ถูกลบใน C ++ 20 สำหรับไลบรารีมาตรฐานหลายประเภท?


44

อ้างอิงจากcppreference , std::type_info::operator!=ถูกลบด้วย C ++ 20, แต่std::type_info::operator==ดูเหมือนว่ายังคงอยู่

อะไรคือเหตุผลเบื้องหลัง ฉันอาจเห็นด้วยว่าการเปรียบเทียบความไม่เท่าเทียมนั้นไร้ความหมาย แต่จากนั้นการเปรียบเทียบความเท่าเทียมจะไม่มีความหมายเช่นกันใช่ไหม

ในทำนองเดียวกันoperator!=ชนิดไลบรารีมาตรฐานอื่น ๆ อีกมากมายรวมถึงคอนเทนเนอร์เช่นstd::unordered_map::operator!=และstd::unordered_set::operator!=จะถูกลบใน C ++ 20 ตาม cppreference

ต้องเขียนif(!(id1 == id2))ไม่ทำให้รหัสใด ๆ ที่ชัดเจนเมื่อเทียบกับif(id1 != id2)ในทางตรงกันข้าม ...

คำตอบ:


62

ใน C ++ 20 วิธีการที่ผู้ประกอบการทำงานเชิงสัมพันธ์ก็เปลี่ยนสะดุดตาด้วยการแนะนำของยานอวกาศที่<=>ผู้ประกอบการ โดยเฉพาะอย่างยิ่งถ้าคุณเพียง แต่ให้operator==แล้วจะเขียนใหม่เพื่อa != b!(a == b)

จาก[over.match.oper] /3.4 :

ชุดตัวเลือก rewritten ถูกกำหนดดังนี้:

  • สำหรับตัวดำเนินการสัมพันธ์ ([expr.rel]) ผู้สมัครที่เขียนใหม่จะรวมผู้สมัครที่ไม่ได้เขียนใหม่ทั้งหมดสำหรับนิพจน์ x <=> y
  • สำหรับตัวดำเนินการเชิงสัมพันธ์ ([expr.rel]) และการเปรียบเทียบสามทาง ([expr.spaceship]) ผู้สมัครที่เขียนใหม่ยังรวมผู้สมัครที่สังเคราะห์ด้วยคำสั่งของพารามิเตอร์ทั้งสองกลับด้านสำหรับผู้สมัครที่ไม่ได้เขียนใหม่สำหรับ นิพจน์ y <=> x
  • สำหรับตัวดำเนินการ! = ([expr.eq]) ผู้สมัครที่เขียนใหม่จะรวมผู้สมัครที่ไม่ได้เขียนใหม่ทั้งหมดสำหรับนิพจน์ x == y
  • สำหรับโอเปอเรเตอร์ความเท่าเทียมกันผู้สมัครที่เขียนใหม่ยังรวมผู้สมัครที่สังเคราะห์ด้วยคำสั่งของพารามิเตอร์ทั้งสองกลับด้านสำหรับผู้สมัครที่ไม่ได้เขียนใหม่สำหรับการแสดงออก y == x
  • สำหรับตัวดำเนินการอื่นทั้งหมดชุดตัวเลือกที่เขียนใหม่จะว่างเปล่า

และ[over.match.oper] / 9 :

หากโอเปอเรเตอร์ที่เขียนใหม่ == ตัวเลือกถูกเลือกโดยการแก้ปัญหาโอเวอร์โหลดสำหรับโอเปอเรเตอร์ @ ชนิดส่งคืนจะเป็น cv bool และ x @ y ถูกตีความว่าเป็น:

  • ถ้า @ คือ! = และผู้สมัครที่เลือกเป็นผู้สมัครสังเคราะห์ที่มีลำดับที่กลับรายการของพารามิเตอร์,! (y == x),
  • มิฉะนั้นถ้า @ เป็น! =! (x == y) ,
  • มิฉะนั้น (เมื่อ @ คือ ==), y == x

ในแต่ละกรณีโดยใช้ตัวดำเนินการเขียนใหม่ที่เลือก == ตัวเลือก

ดังนั้นการโอเวอร์โหลดที่ชัดเจนสำหรับoperator!=จึงไม่จำเป็นอีกต่อไป การลบโอเปอเรเตอร์ไม่ได้เปลี่ยนซีแมนทิกส์การเปรียบเทียบ

ตู้คอนเทนเนอร์ทั้งหมดได้operator!=ถูกลบออกไปเท่าที่ฉันสามารถบอกได้ (ตรวจสอบเช่นเรื่องย่อของเวกเตอร์ ) ข้อยกเว้นเพียงอย่างเดียวคืออะแดปเตอร์คอนเทนเนอร์std::queueและstd::stack: ฉันเดาว่ามันคือการรักษาความเข้ากันได้ย้อนหลังเมื่อใช้กับคอนเทนเนอร์ของบุคคลที่สามในกรณีที่ตัวดำเนินการความเท่าเทียมกันไม่สมมาตร


7
p1614อาจเป็นที่สนใจเช่นกันเพราะฉันเชื่อว่าเป็นข้อเสนอที่ลบการโอเวอร์โหลด
N. Shead

39

เราไม่ต้องการห้องสมุดที่ให้operator!=อีกต่อไป การให้operator==อนุญาตให้คอมไพเลอร์ทำการเล่นปาหี่และประเมินผลa != bในแง่ของa == bทั้งหมดด้วยตัวเอง

[over.match.oper]

3สำหรับตัวดำเนินการ unary @ ที่มีตัวถูกดำเนินการชนิดที่มี cv-unqualified version คือ T1 และสำหรับตัวดำเนินการไบนารี @ ที่มีตัวถูกดำเนินการด้านซ้ายของชนิดที่มีรุ่น cv-unqualified version คือ T1 และตัวถูกดำเนินการด้านขวา รุ่นที่ไม่มีเงื่อนไขคือ T2, สี่ชุดของฟังก์ชั่นผู้สมัคร, ผู้สมัครสมาชิกที่ได้รับมอบหมาย, ผู้สมัครที่ไม่ใช่สมาชิก, ผู้สมัครในตัวและผู้สมัครใหม่, ถูกสร้างขึ้นดังนี้:

3.4.3สำหรับตัวดำเนินการ! = ([expr.eq]) ผู้สมัครที่เขียนใหม่จะรวมผู้สมัครที่ไม่ได้เขียนใหม่ทั้งหมดสำหรับนิพจน์ x == y

std::type_infoและประเภทห้องสมุดอื่น ๆ อีกมากมายได้operator!=ถูกลบออกไปเป็นส่วนหนึ่งของP1614 - The Mothership นั้นได้ลงจอดแล้ว

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