Apa pro / kontra untuk menggunakan auto
kata kunci, terutama untuk loop?
for(std::vector<T>::iterator it = x.begin(); it != x.end(); it++ )
{
it->something();
}
for(std::map<T>::iterator it = x.begin(); it != x.end(); it++ )
{
it->second->something();
}
for(auto it = x.begin(); it != x.end(); it++ )
{
it->??
}
Sepertinya jika Anda tidak tahu apakah Anda memiliki iterator untuk peta atau vektor Anda tidak akan tahu apakah akan digunakan first
atau second
atau hanya langsung akses properti dari objek, tidak ada?
Ini mengingatkan saya pada perdebatan C # tentang apakah akan menggunakan kata kunci var
. Kesan yang saya dapatkan sejauh ini adalah bahwa di dunia C ++ orang siap untuk mengadopsi auto
kata kunci dengan sedikit perkelahian daripada var
di dunia C #. Bagi saya insting pertama saya adalah saya suka mengetahui jenis variabelnya sehingga saya bisa tahu operasi apa yang dapat saya lakukan untuk melakukannya.
var
? Saya melewatkan itu.for (auto& it : x)
(atau tanpa referensi jika Anda ingin menyalin)x
dan Anda bahkan tidak tahu apax
itu, Anda seharusnya tidak menulis loop itu di tempat pertama ;-)Jawaban:
Motivasi dalam C ++ lebih ekstrim, karena tipe bisa menjadi jauh lebih berbelit-belit dan kompleks daripada tipe C # karena metaprogramming dan hal-hal lain.
auto
lebih cepat untuk menulis dan membaca dan lebih fleksibel / dipelihara daripada jenis eksplisit. Maksud saya, apakah Anda ingin mulai mengetikItu bahkan bukan tipe lengkap. Saya melewatkan beberapa argumen templat.
sumber
auto
. Dengan desain.typedef
membantu, tetapiauto
membantu lebih banyak.Dalam contoh Anda:
harus ada deklarasi agar
x
terlihat. Karena itu jenisnyait
harus jelas. Jika jenisnyax
tidak jelas, maka metodenya terlalu panjang, atau kelasnya terlalu besar.sumber
x
nama variabel yang sangat buruk untuk sebuah wadah. Dalam beberapa situasi Anda kemungkinan besar hanya dapat melihat nama (bernilai semantik) dan menyimpulkan operasi yang mungkin.x
sebagai contoh umum, saya cenderung menggunakan nama variabel yang cukup deskriptif.Keberatan ! Pertanyaan yang dimuat.
Bisakah Anda menjelaskan kepada saya mengapa kode ketiga ada
??
di dalamnya, namun yang pertama dan kedua tidak? Demi keadilan, kode Anda harus dibaca sebagai berikut:Sana. Masalah yang sama meskipun Anda tidak menggunakannya
auto
.Dan dalam semua kasus, jawabannya sama: Konteks penting . Anda tidak dapat berbicara secara bermakna tentang sepotong kode secara terpisah. Bahkan jika Anda tidak menggunakan template tetapi beberapa tipe konkret, ini hanya akan memindahkan masalah ke tempat lain, karena pembaca kode Anda harus tahu tentang deklarasi tipe tersebut.
Jika penggunaan
auto
dalam situasi itu membuat kode Anda tidak dapat dibaca, Anda harus memperlakukan ini sebagai tanda peringatan bahwa ada sesuatu yang salah dengan desain kode Anda. Tentu saja, ada kasus-kasus di mana rincian tingkat rendah penting (seperti ketika berhadapan dengan operasi bit atau legacy API) di mana kasus tipe eksplisit dapat membantu keterbacaan. Namun secara umum - tidak.Mengenai
var
(karena Anda menyebutkannya secara eksplisit), ada juga konsensus luas dalam komunitas C # untuk digunakanvar
. Argumen yang menentang penggunaannya umumnya dibangun di atas kekeliruan .sumber
T
sama buramnya dengan penggunaauto
. Namun yang satu seharusnya baik-baik saja dan yang lainnya tidak ?! Itu tidak masuk akal. Dalam kasus OP,T
adalah stand-in untuk tipe yang sewenang-wenang. Dalam kode nyata, mungkin penggunaan templat(for typename std::vector<T>::iterator…)
atau antarmuka kelas. Dalam kedua kasus, tipe aktual disembunyikan dari pengguna, namun kami secara rutin menulis kode seperti itu tanpa masalah.auto
. Itu sepele untuk melihat operasi apa yangx
didukung dari konteks. Bahkan, jenis memberi Anda tidak ada informasi tambahan: dalam kedua kasus Anda membutuhkan sekunder (IDE, dokumentasi, pengetahuan / memori) untuk memberitahu Anda set operasi yang didukung.begin
hasil tetapi Anda tidak tahu apastd::vector<>::iterator
yang. Dan Anda perlu menggunakan alat pemrograman yang buruk yang tidak bisa memberi Anda informasi ini sepele. Ini sangat berbelit-belit. Pada kenyataannya, Anda tahu keduanyabegin
daniterator
atau tidak sama sekali, dan Anda harus menggunakan IDE atau editor yang dapat dengan mudah menyediakan informasi yang relevan bagi Anda. Setiap IDE dan editor pemrograman modern dapat melakukannya.PRO
Kode Anda:
tidak akan dikompilasi, karena nama yang bergantung pada templat.
Ini adalah sintaks yang benar:
Sekarang lihat berapa lama deklarasi jenisnya. Ini menjelaskan mengapa
auto
kata kunci diperkenalkan. Ini:lebih ringkas. Jadi, ini adalah pro.
MENIPU
Anda harus sedikit berhati-hati. Dengan kata kunci
auto
, Anda mendapatkan tipe yang Anda nyatakan.Sebagai contoh :
vs.
Untuk menyimpulkan: ya, Anda harus melakukannya, tetapi tidak menggunakannya secara berlebihan. Beberapa orang cenderung menggunakannya terlalu banyak, dan menempatkan otomatis di mana-mana, seperti pada contoh berikut:
vs.
sumber
auto i = 0
. Bersalah. Saya melakukannya. Tapi itu karena saya tahu itu0
adalah tipe literalint
. (dan konstanta oktal ;-))Ya kamu harus!
auto
tidak menghapus tipe; bahkan jika Anda "tidak tahu" apax.begin()
itu, kompiler tahu dan akan melaporkan kesalahan jika Anda mencoba menggunakan jenis itu secara salah. Juga, tidak biasa untuk ditirumap
dengan avector<pair<Key,Value>>
, sehingga penggunaan kodeauto
akan bekerja untuk kedua representasi kamus.sumber
Ya, Anda harus menggunakan
auto
sebagai aturan default. Ini memiliki keuntungan mentah dibandingkan dengan menentukan jenis:Di sinilah Anda punya pilihan. Ada juga kasus di mana Anda tidak punya pilihan:
Asalkan Anda tahu persis apa yang
auto
dilakukan, itu tidak memiliki kerugian.sumber