Saya tahu bahwa di C ++ 11 sekarang kita dapat menggunakan using
untuk menulis tipe alias, seperti typedef
s:
typedef int MyInt;
Apakah, dari apa yang saya mengerti, setara dengan:
using MyInt = int;
Dan sintaks baru itu muncul dari upaya untuk memiliki cara untuk mengekspresikan " template typedef
":
template< class T > using MyType = AnotherType< T, MyAllocatorType >;
Tetapi, dengan dua contoh non-templat pertama, apakah ada perbedaan halus lainnya dalam standar? Misalnya, typedef
lakukan aliasing dengan cara "lemah". Itu tidak membuat jenis baru tetapi hanya nama baru (konversi tersirat di antara nama-nama).
Apakah sama dengan using
atau apakah itu menghasilkan tipe baru? Apakah ada perbedaan?
c++
c++11
typedef
using-declaration
Klaim
sumber
sumber
typedef void (&MyFunc)(int,int);
atau tidakusing MyFunc = void(int,int);
?typedef void MyFunc(int,int);
(yang sebenarnya tidak terlihat buruk), atauusing MyFunc = void(&)(int,int);
using MyFunc = void(&)(int,int);
? Apakah maksudnyaMyFunc
adalah referensi ke suatu fungsi? bagaimana jika Anda menghilangkan & ?typedef void (&MyFunc)(int,int);
. Jika Anda menghilangkan&
itu setara dengantypedef void MyFunc(int,int);
Jawaban:
Mereka setara, dari standar (tambang penekanan) (7.1.3.2):
sumber
using
kata kunci tampaknya menjadi superset daritypedef
. Lalu, apakahtypdef
akan ditinggalkan di masa depan?using
sintaksis tepatnya karenatypedef
semantik tidak bekerja dengan baik dengan template. Yang entah bagaimana bertentangan dengan fakta yangusing
didefinisikan memiliki semantik yang persis sama.n1489
. Alias templat bukan alias untuk jenis, tetapi alias untuk sekelompok templat. Untuk membuat perbedaan antaratypedef
yang dirasa perlu sintaksis baru. Juga, perlu diingat pertanyaan OP adalah tentang perbedaan antara versi non-template.typdef
pernah merasa ditinggalkan.Mereka sebagian besar sama, kecuali bahwa:
sumber
typedef
jika saya dapat bertanya?The menggunakan sintaks memiliki keuntungan ketika digunakan dalam template. Jika Anda memerlukan abstraksi jenis, tetapi juga perlu menjaga parameter templat agar dapat ditentukan di masa mendatang. Anda harus menulis sesuatu seperti ini.
Tetapi menggunakan sintaksis menyederhanakan use case ini.
sumber
Mereka pada dasarnya sama tetapi
using
menyediakanalias templates
yang cukup berguna. Satu contoh bagus yang bisa saya temukan adalah sebagai berikut:Jadi, kita bisa menggunakan
std::add_const_t<T>
bukannyatypename std::add_const<T>::type
sumber
Saya tahu poster asli memiliki jawaban yang bagus, tetapi bagi siapa pun yang tersandung pada utas ini seperti yang saya miliki ada catatan penting dari proposal yang menurut saya menambah sesuatu yang bernilai untuk diskusi di sini, terutama untuk keprihatinan dalam komentar tentang apakah
typedef
kata kunci tersebut akan ditandai sebagai usang di masa mendatang, atau dihapus karena menjadi redundan / lama:Bagi saya, ini menyiratkan dukungan berkelanjutan untuk
typedef
kata kunci dalam C ++ karena masih dapat membuat kode lebih mudah dibaca dan dimengerti .Memperbarui
using
kata kunci khusus untuk templat, dan (seperti yang ditunjukkan dalam jawaban yang diterima) ketika Anda bekerja dengan non-templatusing
dantypedef
identik secara mekanis, sehingga pilihannya sepenuhnya tergantung pada programmer dengan alasan keterbacaan dan komunikasi maksud. .sumber
Kedua kata kunci itu setara, tetapi ada beberapa peringatan. Salah satunya adalah bahwa mendeklarasikan pointer fungsi dengan
using T = int (*)(int, int);
lebih jelas daripada dengantypedef int (*T)(int, int);
. Kedua adalah bahwa bentuk alias template tidak mungkin dengantypedef
. Ketiga adalah bahwa mengekspos C API akan membutuhkantypedef
di header publik.sumber
Deklarasi typedef dapat, sedangkan deklarasi alias tidak bisa, digunakan sebagai pernyataan inisialisasi
Meskipun kasus sudut, deklarasi typedef adalah init-statement dan dengan demikian dapat digunakan dalam konteks yang memungkinkan pernyataan inisialisasi
sedangkan alias-deklarasi adalah bukan sebuah init-pernyataan , dan mungkin dengan demikian tidak digunakan dalam konteks yang memungkinkan pernyataan inisialisasi
sumber