Apakah menjadi tipe POD persis sama dengan menjadi tipe standar-sepele?

22

Dalam C ++ 20, konsep POD sudah usang, konon karena itu adalah sifat komposit yang tidak berarti menjadi sepele dan tata letak standar. Namun, definisi POD dalam konsep C ++ 20 tidak persis "keduanya sepele dan tata letak standar"; sebenarnya:

Kelas POD adalah kelas yang merupakan kelas trivial dan kelas tata letak standar, dan tidak memiliki anggota data non-statis dari tipe kelas non-POD (atau lariknya). Tipe POD adalah tipe skalar, kelas POD, array tipe seperti itu, atau versi yang memenuhi syarat cv dari salah satu tipe ini.

Dengan kata lain, tidak hanya tipe POD yang sepele dan tata letak standar, tetapi juga secara rekursif.

Apakah persyaratan rekursif ini berlebihan? Dengan kata lain, jika suatu tipe sepele dan tata letak standar, apakah secara otomatis rekursif sepele dan tata letak standar juga? Jika jawabannya "tidak", lalu apa contoh dari tata letak standar, tipe sepele yang gagal menjadi POD?

Brian
sumber

Jawaban:

12

Dalam C ++ 20, konsep POD sudah usang, konon karena itu adalah sifat komposit yang tidak berarti menjadi sepele dan tata letak standar.

Salah. Istilah POD sedang tidak digunakan lagi karena tidak lagi penting :

Istilah POD tidak lagi memenuhi tujuan dalam standar, itu hanya didefinisikan, dan pembatasan berlaku ketika beberapa jenis lain mempertahankan properti peninggalan ini.

Pada dasarnya, tipe yang sepele dan tata letak standar tidak mendapatkan kemampuan apa pun di luar apa yang menjadi sepele dan tata letak standar menyediakan sendiri. Kombinasi keduanya tidak membuat tipe tersebut spesial, dan kedua properti tersebut tidak terlalu berhubungan satu sama lain.

Tata letak standar adalah tentang tata letak sub-objek non-kosongnya yang terdefinisi dengan baik (serta sub-objek kelas dasar kosong yang tidak mengganggu tata letak jenis ini). Triviality adalah tentang apakah objek memiliki makna di luar blok bit yang disimpannya (dan apakah objek tersebut secara konsep merupakan objek yang valid jika diinisialisasi dengan blok bit yang arbitrer).

Jika saya membuat template yang menggunakan tipe T, dan saya ingin melihat apakah saya bisa memcpyobjek dari tipe itu, saya tidak peduli dengan tata letak anggotanya; Saya ingin tahu apakah itu TriviallyCopyable. Demikian pula, kebenaran offsetoftidak peduli sedikit pun jika kelas memiliki copy constructor yang disediakan pengguna. Yang perlu diperhatikan adalah jika tata letak sub-objek anggota terjadi dalam urutan yang jelas dan diberlakukan standar.

Pada dasarnya, orang-orang melihat sekeliling dan menyadari bahwa tidak ada yang tersisa di C ++ yang secara khusus membutuhkan persimpangan dari hal-hal sepele dan tata letak standar. Jadi kita tidak perlu memesan istilah untuk itu. Beberapa tempat di mana standar menyatakan secara tegas bahwa beberapa jenis akan "POD" dapat dengan mudah digantikan oleh "tata letak sepele dan standar", yang sesuai.

Apakah persyaratan rekursif ini berlebihan?

Karena kedua persyaratan konstituen tersebut bersifat rekursif secara individual, persimpangan keduanya juga bersifat rekursif. Jadi tidak ada kebutuhan eksplisit untuk menyatakan bahwa semua sub-proyek juga POD. Ini lebih dari kemungkinan hanya kasus keanehan copy-and-paste, di mana definisi asli mengatakan sesuatu seperti "semua anggota data non-statis harus tipe POD" dan mereka hanya menjaga pernyataan itu sebagaimana adanya.

Nicol Bolas
sumber
" Yang perlu diperhatikan adalah jika tata letak sub-objek anggota terjadi dalam urutan yang jelas dan diberlakukan standar " Mengapa std harus menegakkan perintah untuk dapat menentukan offset anggota? Apakah ini merupakan tujuan std untuk memungkinkan impl gila di mana anggota tidak memiliki offset?
curiousguy
1

Tata letak standar tergantung pada tata letak standar anggota non-statis:

[class.prop]

Kelas S adalah kelas tata letak standar jika:

  • tidak memiliki anggota data non-statis dari kelas tipe non-standar-tata letak (atau array jenis seperti itu) atau referensi,

  • ...

Triviality juga tergantung pada triviality anggota non-statis. Untuk keringkasan, saya hanya mengutip aturan untuk konstruktor default, tetapi fungsi anggota khusus lainnya memiliki kata-kata yang serupa:

[class.default.ctor]

Konstruktor default tidak penting jika tidak disediakan pengguna dan jika:

  • ...
  • untuk semua anggota data non-statis kelasnya yang bertipe kelas (atau lariknya), masing-masing kelas tersebut memiliki destruktor sepele.

Sejauh yang saya tahu, persyaratan eksplisit dari PODness untuk diterapkan pada anggota adalah mubazir, karena persyaratan tersebut juga secara implisit mengikuti dari persyaratan tata letak standar dan sepele.

eerorika
sumber