C ++ 0x menambahkan dukungan inferensi tipe komprehensif yang sangat sangat rumit. Saya sangat tergoda untuk menggunakannya sedapat mungkin untuk menghindari pengulangan yang tidak semestinya, tapi saya bertanya-tanya apakah menghapus informasi jenis eksplisit di semua tempat adalah ide yang bagus. Pertimbangkan contoh yang agak dibuat-buat ini:
Foo.h
:
#include <set>
class Foo {
private:
static std::set<Foo*> instances;
public:
Foo();
~Foo();
// What does it return? Who cares! Just forward it!
static decltype(instances.begin()) begin() {
return instances.begin();
}
static decltype(instances.end()) end() {
return instances.end();
}
};
Foo.cpp
:
#include <Foo.h>
#include <Bar.h>
// The type need only be specified in one location!
// But I do have to open the header to find out what it actually is.
decltype(Foo::instances) Foo::instances;
Foo() {
// What is the type of x?
auto x = Bar::get_something();
// What does do_something() return?
auto y = x.do_something(*this);
// Well, it's convertible to bool somehow...
if (!y) throw "a constant, old school";
instances.insert(this);
}
~Foo() {
instances.erase(this);
}
Apakah Anda mengatakan ini masuk akal, atau benar-benar konyol? Lagi pula, terutama jika Anda terbiasa berkembang dalam bahasa yang dinamis, Anda tidak benar-benar perlu peduli banyak tentang jenis hal, dan dapat percaya bahwa kompiler akan menangkap setiap penyalahgunaan mengerikan dari sistem tipe. Tetapi bagi Anda yang mengandalkan dukungan editor untuk tanda tangan metode, Anda kurang beruntung, jadi menggunakan gaya ini di antarmuka perpustakaan mungkin merupakan praktik yang sangat buruk.
Saya menemukan bahwa menulis hal-hal dengan semua jenis yang mungkin implisit sebenarnya membuat kode saya jauh lebih mudah bagi saya untuk diikuti, karena menghapus hampir semua kekacauan biasa dari C ++. Jarak tempuh Anda mungkin, tentu saja, bervariasi, dan itulah yang saya minati. Apa keuntungan dan kerugian spesifik dari penggunaan radikal inferensi tipe?
sumber
Jawaban:
Menjadi programmer Python sendiri, saya berbagi pola pikir bahwa programmer tidak perlu tahu tipe yang tepat. Dalam kasus C ++, terutama ketika berhadapan dengan templated templated templated ... templates. Tentu saja itu bukan karena saya membenci pengetikan statis (saya tidak - saya menganggap Haskell salah satu hal terbaik sejak mengiris roti, sebagian karena pengetikan statisnya) tetapi karena saya tidak peduli dengan jenis pastinya. Mengapa, tidak ditunjukkan dengan baik oleh contoh yang menggunakan nama seperti
foo
atauget_stuff()
. Jadi mari kita pilih sesuatu yang lebih dekat dengan kenyataan:Bukan anotasi jenis tunggal, tetapi sangat jelas apa fungsinya, bukan? Kode ini tidak peduli apa jenisnya
users
, hanya perlu beberapa rentang untuk beralih yang berisi hal-halname
yang dapat diumpankancheck_name
. Tidak ada lagi. Tidak ada yang peduli dengan karakter 100-ish dari nama ketik yang harus Anda ketik sebaliknya.Hal yang sama berlaku untuk sebagian besar kode dengan nama yang bermakna. Contoh dalam pertanyaan tidak jelas, tetapi juga tidak akan jelas dengan nama jenis eksplisit, karena baik konteks maupun pengidentifikasi tidak memberikan indikasi apa pun yang terjadi. Gunakan pengidentifikasi yang bermakna, dan kode dapat dipahami terlepas dari anotasi jenis eksplisit.
sumber
Alasan mereka menarik kesimpulan adalah untuk mencegah orang menulis kode seperti:
Kapan Anda bisa menulis:
Kecuali Foo akan menjadi tipe templated lama, jadi lebih baik untuk menulis:
Jadi, sebagai aturan praktis, jika menggunakan otomatis menyebabkan Anda menulis kode seperti di atas, bukan kode yang mirip dengan contoh pertama maka dengan segala cara menggunakannya. Jika tidak, tetap tambahkan definisi eksplisit.
sumber
auto
dalam banyak kasus di mana saya yakin orang lain akan eksplisit, tetapi saya tidak melihat apa yang sebenarnya salah dengan, katakanlahauto f = new SomethingLong()
, karena jelas apa yang dikembalikan oleh ekspresi. Saya hanya ingin tahu di mana menggambar garis.SomethingLong
bukan bagian dari struktur warisan, tetapi kecuali Anda yakin tidak akan pernah ada maka saya akan menyarankan untuk tidak melakukannya. Jauh lebih mudah untuk menarik garis pada sisi yang berhati-hati.Ada alasan bagus untuk tidak selalu menggunakan inferensi tipe. Haskell memiliki tipe inferensi, tetapi saya biasanya mendeklarasikan tipe fungsi secara eksplisit. Itu sebagian akibat dari gaya perkembangan saya. Saya menyatakan fungsi terlebih dahulu:
Selanjutnya, saya akan menulis kode yang menggunakan fungsi itu dan melakukan kompilasi untuk memastikannya mengetik cek. Setelah mengetik cek, saya akan melanjutkan dengan implementasi.Alasan lain untuk mendeklarasikan tipe fungsi adalah bahwa deklarasi dapat berfungsi sebagai dokumentasi tambahan. Dokumentasi ini diverifikasi pada setiap kompilasi adalah bonus.
sumber