Informasi berikut sudah ketinggalan zaman. Ini perlu diperbarui sesuai dengan draf Konsep Lite terbaru.
Bagian 3 dari proposal kendala mencakup ini secara mendalam.
Proposal konsep telah diletakkan di belakang pembakar untuk sementara waktu dengan harapan bahwa kendala (yaitu konsep-lite) dapat menyempurnakan dan diterapkan dalam skala waktu yang lebih singkat, saat ini bertujuan untuk setidaknya sesuatu dalam C ++ 14. Proposal kendala dirancang untuk bertindak sebagai transisi yang mulus ke definisi konsep selanjutnya. Batasan adalah bagian dari proposal konsep dan merupakan blok bangunan yang diperlukan dalam definisinya.
Di Design of Concept Libraries untuk C ++ , Sutton dan Stroustrup mempertimbangkan hubungan berikut:
Konsep = Batasan + Aksioma
Untuk meringkas artinya dengan cepat:
- Constraint - Predikat atas properti suatu tipe yang dapat dievaluasi secara statis. Persyaratan sintaksis murni. Bukan abstraksi domain.
- Aksioma - Persyaratan semantik dari jenis yang dianggap benar. Tidak diperiksa secara statis.
- Konsep - Persyaratan umum dan abstrak dari algoritme pada argumennya. Didefinisikan dalam batasan dan aksioma.
Jadi jika Anda menambahkan aksioma (properti semantik) ke batasan (properti sintaksis), Anda mendapatkan konsep.
Konsep-Lite
Proposal konsep-ringan hanya memberi kita bagian pertama, kendala, tetapi ini adalah langkah penting dan perlu menuju konsep yang lengkap.
Kendala
Batasan adalah tentang sintaks . Mereka memberi kita cara membedakan properti suatu tipe secara statis pada waktu kompilasi, sehingga kita dapat membatasi tipe yang digunakan sebagai argumen template berdasarkan properti sintaksisnya. Dalam proposal kendala saat ini, mereka diekspresikan dengan subset dari kalkulus proposisional menggunakan penghubung logis seperti &&dan ||.
Mari kita lihat kendala dalam tindakan:
template <typename Cont>
requires Sortable<Cont>()
void sort(Cont& container);
Di sini kita mendefinisikan template fungsi yang disebut sort. Penambahan baru adalah klausa yang dibutuhkan . Klausa require memberikan beberapa batasan pada argumen template untuk fungsi ini. Secara khusus, batasan ini mengatakan bahwa tipe Contharus berupa Sortabletipe. Hal yang rapi adalah dapat ditulis dalam bentuk yang lebih ringkas seperti:
template <Sortable Cont>
void sort(Cont& container);
Sekarang jika Anda mencoba meneruskan apa pun yang tidak dianggap Sortableuntuk fungsi ini, Anda akan mendapatkan kesalahan bagus yang segera memberi tahu Anda bahwa tipe yang disimpulkan untuk Tbukanlah Sortabletipe. Jika Anda telah melakukan ini di C ++ 11, Anda akan memiliki beberapa kesalahan yang mengerikan terlempar dari dalam yang sortfungsi yang tidak masuk akal untuk siapa pun.
Predikat kendala sangat mirip dengan sifat tipe. Mereka mengambil beberapa tipe argumen template dan memberi Anda beberapa informasi tentangnya. Constraints mencoba menjawab jenis pertanyaan berikut tentang type:
- Apakah tipe ini memiliki operator ini dan itu kelebihan beban?
- Apakah tipe ini dapat digunakan sebagai operan untuk operator ini?
- Apakah tipe ini memiliki sifat ini dan itu?
- Apakah ekspresi konstan ini sama dengan itu? (untuk argumen template non-tipe)
- Apakah tipe ini memiliki fungsi yang disebut yada-yada yang mengembalikan tipe tersebut?
- Apakah tipe ini memenuhi semua persyaratan sintaksis untuk digunakan seperti itu?
Namun, kendala tidak dimaksudkan untuk menggantikan sifat tipe. Sebaliknya, mereka akan bekerja sama. Beberapa sifat tipe sekarang dapat didefinisikan dalam istilah konsep dan beberapa konsep dalam istilah sifat tipe.
Contoh
Jadi yang penting tentang kendala adalah mereka tidak peduli tentang semantik sedikit pun. Beberapa contoh kendala yang baik adalah:
Equality_comparable<T>: Memeriksa apakah tipe memiliki ==kedua operan dari tipe yang sama.
Equality_comparable<T,U>: Memeriksa apakah ada ==operan dengan kiri dan kanan dari tipe yang diberikan
Arithmetic<T>: Memeriksa apakah tipenya adalah tipe aritmatika.
Floating_point<T>: Memeriksa apakah tipenya adalah tipe floating point.
Input_iterator<T>: Memeriksa apakah tipe mendukung operasi sintaksis yang harus didukung oleh iterator masukan.
Same<T,U>: Memeriksa apakah tipe yang diberikan sama.
Anda dapat mencoba semua ini dengan GCC konsep-lite khusus .
Beyond Concepts-Lite
Sekarang kita membahas segala hal di luar proposal konsep-ringan. Ini bahkan lebih futuristik dari masa depan itu sendiri. Segala sesuatu mulai saat ini tampaknya akan sedikit berubah.
Aksioma
Aksioma adalah tentang semantik . Mereka menentukan hubungan, invarian, jaminan kompleksitas, dan hal-hal lain semacam itu. Mari kita lihat contohnya.
Sementara Equality_comparable<T,U>batasan akan memberi tahu Anda bahwa ada operator== yang mengambil tipe Tdan U, itu tidak memberi tahu Anda apa arti operasi itu . Untuk itu, kita akan punya aksioma Equivalence_relation. Aksioma ini mengatakan bahwa ketika objek dari dua tipe ini dibandingkan dengan operator==pemberian true, objek-objek ini adalah setara. Ini mungkin tampak mubazir, tetapi sebenarnya tidak. Anda dapat dengan mudah mendefinisikan operator==bahwa sebagai gantinya berperilaku seperti file operator<. Anda akan jahat melakukan itu, tetapi Anda bisa.
Contoh lainnya adalah Greateraksioma. Baik dan bagus untuk mengatakan dua objek dengan tipe Tdapat dibandingkan dengan operator >dan <, tetapi apa artinya ? The Greateraksioma mengatakan bahwa jika dan hanya jika xlebih besar maka y, maka ykurang dari x. Spesifikasi yang diusulkan aksioma seperti itu terlihat seperti:
template<typename T>
axiom Greater(T x, T y) {
(x>y) == (y<x);
}
Jadi aksioma menjawab jenis pertanyaan berikut:
- Apakah kedua operator ini memiliki hubungan ini satu sama lain?
- Apakah operator untuk tipe ini dan itu berarti demikian?
- Apakah operasi pada tipe itu memiliki kerumitan ini?
- Apakah hasil dari operator tersebut menyiratkan bahwa ini benar?
Artinya, mereka sepenuhnya peduli dengan semantik jenis dan operasi pada jenis tersebut. Hal-hal ini tidak dapat diperiksa secara statis. Jika ini perlu dicentang, suatu jenis harus dengan cara tertentu menyatakan bahwa ia mematuhi semantik ini.
Contoh
Berikut beberapa contoh umum aksioma:
Equivalence_relation: Jika dua objek dibandingkan ==, keduanya setara.
Greater: Kapanpun x > y, lalu y < x.
Less_equal: Kapanpun x <= y, lalu !(y < x).
Copy_equality: Untuk xdan ybertipe T: if x == y, sebuah objek baru dengan tipe yang sama dibuat dengan konstruksi salinan T{x} == ydan masih x == y(yaitu, tidak merusak).
Konsep
Sekarang konsep sangat mudah untuk didefinisikan; mereka hanyalah kombinasi dari kendala dan aksioma . Mereka menyediakan persyaratan abstrak atas sintaks dan semantik suatu tipe.
Sebagai contoh, pertimbangkan Orderedkonsep berikut :
concept Ordered<Regular T> {
requires constraint Less<T>;
requires axiom Strict_total_order<less<T>, T>;
requires axiom Greater<T>;
requires axiom Less_equal<T>;
requires axiom Greater_equal<T>;
}
Pertama perhatikan bahwa untuk tipe template yang Takan Ordered, itu juga harus memenuhi persyaratan Regularkonsep. The Regularkonsep adalah persyaratan yang sangat dasar yang jenisnya adalah berkelakuan baik - itu dapat dibangun, dihancurkan, disalin dan dibandingkan.
Selain persyaratan tersebut, persyaratan Orderedyang Tmemenuhi satu kendala dan empat aksioma:
- Batasan:
OrderedJenis harus memiliki operator<. Ini dicentang secara statis sehingga harus ada.
- Aksioma: Untuk
xdan ydari tipe T:
x < y memberikan pemesanan total yang ketat.
- Kapan
xlebih besar dari y, ylebih kecil dari x, dan sebaliknya.
- Bila
xkurang dari atau sama dengan y, ytidak kurang dari x, dan sebaliknya.
- Kapan
xlebih besar dari atau sama dengan y, ytidak lebih besar dari x, dan sebaliknya.
Menggabungkan kendala dan aksioma seperti ini memberi Anda konsep. Mereka mendefinisikan persyaratan sintaksis dan semantik untuk tipe abstrak untuk digunakan dengan algoritma. Algoritma saat ini harus mengasumsikan bahwa tipe yang digunakan akan mendukung operasi tertentu dan mengekspresikan semantik tertentu. Dengan konsep, kami dapat memastikan bahwa persyaratan terpenuhi.
Dalam desain konsep terbaru , kompilator hanya akan memeriksa bahwa persyaratan sintaksis suatu konsep dipenuhi oleh argumen template. Aksioma dibiarkan tidak dicentang. Karena aksioma menunjukkan semantik yang tidak dapat dievaluasi secara statis (atau seringkali tidak mungkin untuk diperiksa seluruhnya), penulis tipe harus secara eksplisit menyatakan bahwa tipenya memenuhi semua persyaratan konsep. Ini dikenal sebagai pemetaan konsep dalam desain sebelumnya, tetapi sejak itu telah dihapus.
Contoh
Berikut beberapa contoh konsep:
Regular jenis dapat dibangun, dirusak, dapat disalin, dan dapat dibandingkan.
Orderedjenis dukungan operator<, dan memiliki total pemesanan yang ketat dan semantik pemesanan lainnya.
Copyabletipe adalah salinan yang dapat dibangun, dapat dirusak, dan jika xsama dengan ydan xdisalin, salinan juga akan dibandingkan dengan y.
Iteratorjenis jenis harus terkait value_type, reference, difference_type, dan iterator_categoryyang sendiri harus memenuhi konsep-konsep tertentu. Mereka juga harus mendukung operator++dan dapat dibedakan.
Jalan Menuju Konsep
Batasan adalah langkah pertama menuju fitur konsep lengkap C ++. Mereka adalah langkah yang sangat penting, karena menyediakan persyaratan tipe yang dapat diberlakukan secara statis sehingga kita dapat menulis fungsi dan kelas templat yang jauh lebih bersih. Sekarang kita dapat menghindari beberapa kesulitan dan keburukan std::enable_ifdan teman metaprogramming nya.
Namun, ada beberapa hal yang tidak dilakukan oleh proposal kendala:
Ini tidak memberikan bahasa definisi konsep.
Batasan bukanlah peta konsep. Pengguna tidak perlu secara khusus menjelaskan tipenya karena memenuhi batasan tertentu. Mereka secara statis diperiksa menggunakan fitur bahasa waktu kompilasi sederhana.
Implementasi template tidak dibatasi oleh batasan pada argumen template mereka. Artinya, jika template fungsi Anda melakukan sesuatu dengan objek berjenis terbatas yang seharusnya tidak dilakukan, compiler tidak memiliki cara untuk mendiagnosisnya. Proposal konsep berfitur lengkap akan dapat melakukan ini.
Proposal kendala telah dirancang secara khusus sehingga proposal konsep lengkap dapat diperkenalkan di atasnya. Dengan sedikit keberuntungan, transisi itu seharusnya menjadi perjalanan yang cukup mulus. Kelompok konsep mencari untuk memperkenalkan batasan untuk C ++ 14 (atau dalam laporan teknis segera setelahnya), sementara konsep lengkap mungkin mulai muncul sekitar C ++ 17.