pengantar
constexpr
tidak diperkenalkan sebagai cara untuk memberitahu implementasi bahwa sesuatu dapat dievaluasi dalam konteks yang membutuhkan ekspresi konstan ; implementasi yang sesuai telah dapat membuktikan ini sebelum C ++ 11.
Sesuatu yang tidak bisa dibuktikan oleh implementasi adalah maksud dari kode tertentu:
- Apa yang ingin diungkapkan oleh pengembang dengan entitas ini?
- Haruskah kita secara membolehkan kode digunakan dalam ekspresi-konstan , hanya karena itu berfungsi?
Apa jadinya dunia tanpa ini constexpr
?
Katakanlah Anda sedang mengembangkan perpustakaan dan menyadari bahwa Anda ingin dapat menghitung jumlah setiap bilangan bulat dalam interval (0,N]
.
int f (int n) {
return n > 0 ? n + f (n-1) : n;
}
Kurangnya niat
Kompiler dapat dengan mudah membuktikan bahwa fungsi di atas dapat dipanggil dalam ekspresi konstan jika argumen yang disampaikan diketahui selama terjemahan; tetapi Anda belum menyatakan ini sebagai maksud - itu terjadi begitu saja.
Sekarang orang lain datang, membaca fungsi Anda, melakukan analisis yang sama dengan kompiler; " Oh, fungsi ini dapat digunakan dalam ekspresi konstan!" , dan menulis potongan kode berikut.
T arr[f(10)]; // freakin' magic
Optimalisasi
Anda, sebagai pengembang perpustakaan "luar biasa" , memutuskan bahwa f
akan menyimpan hasil cache ketika dipanggil; siapa yang ingin menghitung set nilai yang sama berulang kali?
int func (int n) {
static std::map<int, int> _cached;
if (_cached.find (n) == _cached.end ())
_cached[n] = n > 0 ? n + func (n-1) : n;
return _cached[n];
}
Hasil
Dengan memperkenalkan optimasi konyol Anda, Anda baru saja melanggar setiap penggunaan fungsi Anda yang kebetulan berada dalam konteks di mana ekspresi konstan diperlukan.
Anda tidak pernah berjanji bahwa fungsi tersebut dapat digunakan dalam ekspresi konstan , dan tanpa itu constexpr
tidak akan ada cara untuk memberikan janji seperti itu.
Jadi, mengapa kita perlu constexpr
?
Penggunaan utama constexpr adalah untuk menyatakan niat .
Jika suatu entitas tidak ditandai sebagai constexpr
- itu tidak pernah dimaksudkan untuk digunakan dalam ekspresi konstan ; dan bahkan jika itu benar, kami bergantung pada kompiler untuk mendiagnosis konteks tersebut (karena itu mengabaikan maksud kami).
constexpr
? Jika demikian, saya dapat melihat penggunaannya.