การเป็นประเภท POD เทียบเท่ากับประเภทเลย์เอาต์มาตรฐานหรือไม่?


22

ใน C ++ 20 แนวคิดของ POD ถูกคัดค้านเนื่องจากเป็นลักษณะประกอบที่ไม่มีความหมายว่าเป็นเรื่องไร้สาระและมีรูปแบบมาตรฐาน อย่างไรก็ตามคำจำกัดความของ PODในร่าง C ++ 20 นั้นไม่ตรงกับ "ทั้งเรื่องธรรมดาและเลย์เอาต์มาตรฐาน" มันเป็นจริง:

คลาส POD เป็นคลาสที่มีทั้งคลาสที่ไม่สำคัญและคลาสเลย์เอาต์มาตรฐานและไม่มีสมาชิกข้อมูลที่ไม่ใช่แบบคงที่ประเภทคลาสที่ไม่ใช่ POD (หรืออาร์เรย์ดังกล่าว) ประเภท POD เป็นประเภทสเกลาร์, คลาส POD, อาร์เรย์ของประเภทดังกล่าวหรือรุ่นที่ผ่านการรับรอง cv ของหนึ่งในประเภทเหล่านี้

กล่าวอีกนัยหนึ่งไม่เพียง แต่จะเป็นประเภท POD ทั้งรูปแบบไม่สำคัญและรูปแบบมาตรฐาน แต่ก็มีรูปแบบซ้ำ ๆ

ข้อกำหนดแบบเรียกซ้ำซ้อนนี้ซ้ำซ้อนหรือไม่ กล่าวอีกนัยหนึ่งถ้าประเภทมีทั้งแบบธรรมดาและแบบเลย์เอาต์มันจะเป็นแบบไม่สำคัญและแบบมาตรฐานแบบซ้ำ ๆ โดยอัตโนมัติหรือไม่? หากคำตอบคือ "ไม่" ดังนั้นตัวอย่างของเลย์เอาต์มาตรฐานประเภทเล็ก ๆ น้อย ๆ ที่ไม่ได้เป็น POD คืออะไร

คำตอบ:


12

ใน C ++ 20 แนวคิดของ POD ถูกคัดค้านเนื่องจากเป็นลักษณะประกอบที่ไม่มีความหมายว่าเป็นเรื่องไร้สาระและมีรูปแบบมาตรฐาน

ไม่ถูกต้อง POD ของคำศัพท์ถูกเลิกใช้เนื่องจากไม่มีความสำคัญอีกต่อไป :

คำว่า POD ไม่ได้มีวัตถุประสงค์ในมาตรฐานอีกต่อไปมันเป็นเพียงการกำหนดและข้อ จำกัด จะมีผลบังคับใช้เมื่อประเภทอื่น ๆ สองสามรักษาคุณสมบัติร่องรอยที่

โดยพื้นฐานแล้วประเภทที่มีทั้งเลย์เอาต์เล็ก ๆ น้อย ๆ และเลย์เอาท์มาตรฐานไม่ได้รับความสามารถใด ๆ นอกเหนือไปจากสิ่งที่ไม่สำคัญ การรวมกันของทั้งสองไม่ได้ทำให้ประเภทพิเศษและคุณสมบัติทั้งสองไม่ได้มีอะไรมากที่จะทำกับคนอื่น

เลย์เอาต์มาตรฐานเป็นเรื่องเกี่ยวกับเลย์เอาต์ของ subobjects ที่ไม่ว่างเปล่าซึ่งถูกกำหนดไว้อย่างดี (เช่นเดียวกับ subobjects คลาสฐานที่ว่างเปล่าซึ่งไม่รบกวนรูปแบบของประเภท) Triviality เป็นเรื่องเกี่ยวกับว่าวัตถุนั้นมีความหมายบางอย่างนอกเหนือจากบล็อกของบิตที่เก็บ (และเป็นแนวคิดที่เป็นวัตถุที่ถูกต้องหรือไม่ถ้ามันถูกกำหนดค่าเริ่มต้นด้วยบล็อกของบิตโดยพลการ)

ถ้าฉันสร้างเทมเพลตที่ใช้ประเภทTและฉันต้องการดูว่าฉันสามารถmemcpyคัดค้านประเภทนั้นได้หรือไม่ฉันไม่สนใจโครงร่างของสมาชิก ฉันต้องการที่จะรู้ว่ามันเป็นเรื่องเล็กน้อยคัดลอก ในทำนองเดียวกันความถูกต้องของoffsetofไม่สนใจน้อยถ้าชั้นมีตัวสร้างสำเนาที่ผู้ใช้ให้ สิ่งที่สำคัญก็คือถ้าเลย์เอาต์ของ subobjects สมาชิกเกิดขึ้นในลำดับที่ชัดเจนบังคับใช้มาตรฐาน

โดยทั่วไปผู้คนมองไปรอบ ๆ และตระหนักว่าไม่มีอะไรเหลือใน C ++ ที่ต้องการการแยกส่วนของเรื่องไร้สาระและเลย์เอาต์มาตรฐาน ดังนั้นเราไม่จำเป็นต้องจองคำสำหรับมัน สถานที่ไม่กี่แห่งที่มาตรฐานระบุอย่างชัดเจนว่าบางประเภทจะเป็น "POD" สามารถถูกแทนที่ด้วย "รูปแบบมาตรฐานและเล็กน้อย" ตามความเหมาะสม

ข้อกำหนดแบบเรียกซ้ำซ้อนนี้ซ้ำซ้อนหรือไม่

เนื่องจากความต้องการขององค์ประกอบทั้งสองซ้ำกันแยกกันการแยกของทั้งสองจึงซ้ำด้วย ดังนั้นจึงไม่จำเป็นต้องระบุอย่างชัดเจนว่า subobjects ทั้งหมดเป็น POD นี่เป็นมากกว่ากรณีของการคัดลอกและวางที่ความหมายดั้งเดิมกล่าวว่าบางสิ่งเช่น "สมาชิกข้อมูลที่ไม่คงที่ทั้งหมดจะต้องเป็นประเภท POD" และพวกเขาก็เก็บคำสั่งนั้นตามที่เป็นอยู่


" สิ่งที่สำคัญคือถ้าเลย์เอาต์ของ subobject ของสมาชิกเกิดขึ้นตามลำดับที่ชัดเจนและบังคับใช้มาตรฐาน " เหตุใด std จึงต้องบังคับใช้คำสั่งเพื่อให้สามารถกำหนดออฟเซ็ตของสมาชิกได้ มันเป็นเป้าหมายของ std หรือไม่ที่จะยอมให้มีการบ้าคลั่งโดยที่สมาชิกไม่มีออฟเซ็ต?
curiousguy

1

เลย์เอาต์มาตรฐานขึ้นอยู่กับเลย์เอาต์มาตรฐานของสมาชิกที่ไม่คงที่:

[class.prop]

คลาส S เป็นคลาสเลย์เอาต์มาตรฐานหาก:

  • ไม่มีสมาชิกข้อมูลที่ไม่คงที่ประเภทคลาสที่ไม่เป็นมาตรฐาน (หรืออาเรย์ประเภทดังกล่าว) หรือการอ้างอิง

  • ...

เรื่องไม่สำคัญยังขึ้นอยู่กับเรื่องไร้สาระของสมาชิกที่ไม่คงที่ เพื่อความกระชับฉันได้อ้างถึงกฎสำหรับตัวสร้างเริ่มต้นเท่านั้น แต่ฟังก์ชันสมาชิกพิเศษอื่น ๆ มีถ้อยคำที่คล้ายกัน:

[class.default.ctor]

ตัวสร้างเริ่มต้นเป็นเรื่องเล็กน้อยถ้ามันไม่ได้ให้ผู้ใช้และถ้า:

  • ...
  • สำหรับสมาชิกข้อมูลที่ไม่คงที่ของคลาสที่เป็นประเภทคลาส (หรืออาเรย์ของมัน) แต่ละคลาสนั้นมี destructor เล็กน้อย

เท่าที่ฉันสามารถบอกได้ข้อกำหนดที่ชัดเจนของ PODness ที่จะนำไปใช้กับสมาชิกนั้นซ้ำซ้อน

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