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 Cont
harus berupa Sortable
tipe. 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 Sortable
untuk fungsi ini, Anda akan mendapatkan kesalahan bagus yang segera memberi tahu Anda bahwa tipe yang disimpulkan untuk T
bukanlah Sortable
tipe. Jika Anda telah melakukan ini di C ++ 11, Anda akan memiliki beberapa kesalahan yang mengerikan terlempar dari dalam yang sort
fungsi 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 T
dan 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 Greater
aksioma. Baik dan bagus untuk mengatakan dua objek dengan tipe T
dapat dibandingkan dengan operator >
dan <
, tetapi apa artinya ? The Greater
aksioma mengatakan bahwa jika dan hanya jika x
lebih besar maka y
, maka y
kurang 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 x
dan y
bertipe T
: if x == y
, sebuah objek baru dengan tipe yang sama dibuat dengan konstruksi salinan T{x} == y
dan 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 Ordered
konsep 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 T
akan Ordered
, itu juga harus memenuhi persyaratan Regular
konsep. The Regular
konsep adalah persyaratan yang sangat dasar yang jenisnya adalah berkelakuan baik - itu dapat dibangun, dihancurkan, disalin dan dibandingkan.
Selain persyaratan tersebut, persyaratan Ordered
yang T
memenuhi satu kendala dan empat aksioma:
- Batasan:
Ordered
Jenis harus memiliki operator<
. Ini dicentang secara statis sehingga harus ada.
- Aksioma: Untuk
x
dan y
dari tipe T
:
x < y
memberikan pemesanan total yang ketat.
- Kapan
x
lebih besar dari y
, y
lebih kecil dari x
, dan sebaliknya.
- Bila
x
kurang dari atau sama dengan y
, y
tidak kurang dari x
, dan sebaliknya.
- Kapan
x
lebih besar dari atau sama dengan y
, y
tidak 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.
Ordered
jenis dukungan operator<
, dan memiliki total pemesanan yang ketat dan semantik pemesanan lainnya.
Copyable
tipe adalah salinan yang dapat dibangun, dapat dirusak, dan jika x
sama dengan y
dan x
disalin, salinan juga akan dibandingkan dengan y
.
Iterator
jenis jenis harus terkait value_type
, reference
, difference_type
, dan iterator_category
yang 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_if
dan 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.