Subjek telah dibahas sebelumnya , tetapi ini bukan duplikat.
Ketika seseorang bertanya tentang perbedaan antara decltype(a)
dan decltype((a))
, jawaban yang biasa adalah - a
adalah variabel, (a)
adalah ekspresi. Saya menemukan jawaban ini tidak memuaskan.
Pertama, a
adalah ekspresi juga. Pilihan untuk ekspresi primer meliputi, antara lain -
- (ekspresi)
- ekspresi-id
Lebih penting lagi, frasa untuk decltype menganggap kurung sangat, sangat eksplisit :
For an expression e, the type denoted by decltype(e) is defined as follows:
(1.1) if e is an unparenthesized id-expression naming a structured binding, ...
(1.2) otherwise, if e is an unparenthesized id-expression naming a non-type template-parameter, ...
(1.3) otherwise, if e is an unparenthesized id-expression or an unparenthesized class member access, ...
(1.4) otherwise, ...
Jadi pertanyaannya tetap. Mengapa kurung diperlakukan berbeda? Adakah yang akrab dengan makalah teknis atau diskusi komite di belakangnya? Pertimbangan eksplisit untuk tanda kurung membuat orang berpikir ini bukan kekhilafan, jadi pasti ada alasan teknis saya tidak ada.
c++
c++11
language-lawyer
decltype
Ofek Shilon
sumber
sumber
(a)
adalah ekspresi, dana
merupakan ekspresi dan variabel".Jawaban:
Itu bukan kekhilafan. Sangat menarik, bahwa dalam Decltype dan otomatis (revisi 4) (N1705 = 04-0145) ada pernyataan:
Tetapi dalam Decltype (revisi 6): kata-kata yang diusulkan (N2115 = 06-018) salah satu perubahannya adalah
Tidak ada alasan dalam pengkalimatannya, tetapi saya kira ini adalah jenis perpanjangan dari jenis pernyataan menggunakan sintaks yang sedikit berbeda, dengan kata lain, itu dimaksudkan untuk membedakan kasus-kasus ini.
Penggunaan untuk itu ditunjukkan dalam C ++ draft9.2.8.4:
Yang benar-benar menarik, adalah cara kerjanya dengan
return
pernyataan:Visual Studio 2019 saya menyarankan saya untuk menghapus tanda kurung yang berlebihan, tetapi sebenarnya mereka berubah menjadi
decltype((i))
perubahan yang mengembalikan nilaiint&
yang menjadikannya UB sejak mengembalikan referensi ke variabel lokal.sumber
Kurung tidak diperlakukan secara berbeda. Ini adalah ekspresi-id yang tidak beradab yang diperlakukan berbeda.
Ketika tanda kurung hadir maka aturan reguler untuk semua ekspresi berlaku. Kategori dan kategori nilai diekstraksi dan dikodifikasi dalam tipe
decltype
.Ketentuan khusus ada di sana sehingga kami dapat menulis kode berguna lebih mudah. Saat menerapkan
decltype
ke nama variabel (anggota), kami biasanya tidak ingin beberapa tipe yang mewakili properti variabel ketika diperlakukan sebagai ekspresi. Alih-alih, kami hanya ingin jenis variabel dideklarasikan dengan, tanpa harus menerapkan satu ton ciri tipe untuk mendapatkannya. Dan itulah tepatnya yangdecltype
ditentukan untuk diberikan kepada kita.Jika kita benar-benar peduli pada properti variabel sebagai ekspresi, maka kita masih bisa mendapatkannya dengan mudah, dengan sepasang kurung tambahan.
sumber
int
anggotai
daria
,decltype(a.i)
yangint
sementaradecltype((a.i))
iniint&
(dengan asumsia
tidakconst
)? Karena ungkapana.i
itu dapat ditentukan?a.i
adalah nilai non-const, sehingga Anda mendapatkan tipe referensi nilai non-const(a.i)
.&
, nilai adalah&&
, dan nilai bukan jenis referensi.Pra C ++ 11 bahasa membutuhkan alat untuk mendapatkan dua jenis informasi yang berbeda :
Karena sifat informasi ini, fitur harus ditambahkan dalam bahasa (tidak dapat dilakukan di perpustakaan). Itu berarti kata kunci baru. Standar dapat memperkenalkan dua kata kunci baru untuk ini. Misalnya
exprtype
untuk mendapatkan jenis ekspresi dandecltype
untuk mendapatkan tipe deklarasi dari suatu variabel. Itu akan menjadi pilihan yang jelas dan bahagia.Namun komite standar selalu berusaha sekuat tenaga untuk menghindari memasukkan kata kunci baru ke dalam bahasa untuk meminimalkan kerusakan kode lama. Kompatibilitas mundur adalah filosofi inti bahasa.
Jadi dengan C ++ 11 kami mendapat hanya satu kata kunci yang digunakan untuk dua hal yang berbeda:
decltype
. Cara membedakan antara kedua kegunaan adalah dengan memperlakukan secaradecltype(id-expression)
berbeda. Itu adalah keputusan sadar oleh komite, kompromi (kecil).sumber
export
diperkenalkan. Jika Anda dapat memilikiexport
(sebelumnya semua templat secara default "diekspor"), Anda dapat memiliki hal-hal sepertidecltype
danconstexpr
. Jelas menambahkanregister
dalam bahasa lain akan bermasalah.