Mengapa saya belajar C ++ 11, setelah mengetahui C dan C ++? [Tutup]

28

Saya seorang programmer di C dan C ++, meskipun saya tidak menggunakan kedua bahasa dan menulis campuran keduanya. Terkadang memiliki kode di kelas, mungkin dengan overloading operator, atau templat dan STL yang sangat bagus jelas merupakan cara yang lebih baik. Kadang-kadang penggunaan pointer fungsi C sederhana jauh lebih mudah dibaca dan jelas. Jadi saya menemukan keindahan dan kepraktisan dalam kedua bahasa. Saya tidak ingin masuk ke diskusi "Jika Anda mencampurnya dan kompilasi dengan kompiler C ++, itu bukan campuran lagi, itu semua C ++" Saya pikir kita semua mengerti apa yang saya maksud dengan mencampurkannya. Juga, saya tidak ingin berbicara tentang C vs C ++, pertanyaan ini adalah semua tentang C ++ 11.

C ++ 11 memperkenalkan apa yang saya pikir merupakan perubahan signifikan pada cara kerja C ++, tetapi C ++ 11 telah memperkenalkan banyak kasus khusus, pengecualian dan penyimpangan yang mengubah cara berbagai fitur berperilaku dalam keadaan yang berbeda, menempatkan batasan pada beberapa pewarisan, pengidentifikasi yang bertindak sebagai kata kunci, ekstensi literal string, penangkapan variabel fungsi lambda, dll.

Saya tahu bahwa di beberapa titik di masa depan, ketika Anda mengatakan C ++ semua orang akan menganggap C ++ 11. Sama seperti ketika Anda mengatakan C saat ini, Anda kemungkinan besar berarti C99. Itu membuat saya mempertimbangkan untuk belajar C ++ 11. Lagi pula, jika saya ingin terus menulis kode dalam C ++, saya mungkin perlu mulai menggunakan fitur-fitur itu hanya karena rekan saya miliki.

Ambil C misalnya. Setelah bertahun-tahun, masih banyak orang yang belajar dan menulis kode dalam C. Mengapa? Karena bahasanya bagus. Apa artinya itu, mengikuti banyak aturan untuk membuat bahasa pemrograman yang baik. Jadi, selain menjadi kuat (yang mudah atau sulit, hampir semua bahasa pemrograman), C teratur dan memiliki beberapa pengecualian, jika ada. C ++ 11 Namun, saya tidak berpikir begitu. Saya tidak yakin bahwa perubahan yang diperkenalkan di C ++ 11 membuat bahasa lebih baik.

Jadi pertanyaannya adalah: Mengapa saya belajar C ++ 11?


sumber
3
Saya mengerti bahwa seharusnya tidak ada kata kasar C ++ 11 di forum ini dan saya setuju sepenuhnya tentang hal ini: setiap pengembang memiliki hak untuk memiliki selera pribadi mereka mengenai bahasa dan alat pemrograman. Namun, ada masalah yang jauh lebih praktis bagi saya: Saya adalah pengembang C ++ dan saya tidak suka C ++ 11, apakah saya akan dipaksa untuk menggunakan C ++ 11 atau keluar dari pasar / beralih ke bahasa lain di dalam Beberapa tahun?
Giorgio
Yah saya berpikir sedikit tentang itu, tentu saja ada yang lebih modern dari bahasa awal seperti bahasa pemrograman D atau Go. Ini mungkin cocok untuk domain masalah Anda, lebih mudah lebih konsisten, dll. Namun pangsa pasar .. tidak ada pemain kunci di industri yang mendukung D dan bahkan Go tampaknya menjadi salah satu "eksperimen" Google. Jadi motivasi di balik C + +11 harus menjadi perbaikan bermanfaat yang memungkinkan Anda untuk menulis kode yang lebih mudah dibaca, lebih aman dan lebih cepat serta dukungan industri yang luas.
Nils
@giorgio, selama dua tahun terakhir, saya berhenti menggunakan C ++ sebanyak yang saya lakukan sebelumnya (kebanyakan karena menyadari bagaimana penggemar C ++ yang religius, membaca jawaban untuk pertanyaan ini), tetapi saya masih bekerja di perpustakaan C ++ yang saya rela digunakan C ++ 11 untuk. Pengalaman saya adalah ini: C ++ 11 membahas banyak sudut jelek dari C ++, dan itu mengagumkan dan memang itu meningkatkannya. Cara itu memiliki sudut jelek sendiri (lihat posting asli yang belum diedit). Namun, sudut-sudut yang jelek itu tampaknya tidak ada gunanya jika Anda melakukan hal-hal "dengan cara normal" (misalnya tidak menyimpan lambda untuk penggunaan di masa mendatang).
@giorgio, yang saya maksud adalah, C ++ 11 mungkin terlihat buruk di awal, sebenarnya C ++ itu sendiri tampak mengerikan, tetapi jika Anda baik-baik saja dengan C ++, Anda mungkin akan menyukai C ++ 11 juga. Hindari menyentuh bagian-bagiannya yang jelek dan Anda mungkin benar-benar menikmatinya.
@anon: Salah satu cara untuk menghilangkan bagian bahasa yang jelek adalah dengan memotong masa lalu dan memulai bahasa baru, seperti yang dilakukan Apple dengan Swift (untuk menyebutkan hanya satu dari sekian banyak contoh). Berinteraksi dengan kode lawas dapat dilakukan melalui kompilasi terpisah. Masalah dengan C ++ adalah bahwa ia akan diperluas tanpa batas waktu, mungkin karena didukung oleh komunitas penggemar yang secara agama percaya bahwa C ++ adalah satu-satunya bahasa yang benar. Intinya: Saya menemukan C ++ 03 agak jelek tapi itu menyelesaikan pekerjaan, terutama terima kasih kepada perpustakaan seperti Qt dan boost. Di sisi lain, saya akan menjaga tangan saya dari C ++ 11.
Giorgio

Jawaban:

24

Anda harus mempelajarinya jika Anda merasa perlu mengetahuinya di masa depan untuk mendapatkan pekerjaan. Jika Anda yakin Anda akan tetap dapat dipasarkan di dunia kerja sebagai C / C ++ [dan apa pun yang mungkin Anda ketahui] maka jangan mempelajarinya. Jika bos Anda memberi tahu Anda untuk menggunakan C ++ 11, katakan "tidak, saya tidak melakukan itu". Jika dia memecat Anda, pergi bekerja di tempat lain. Pelajari C ++ 11 ketika Anda memperkirakan bahwa segera Anda tidak akan dapat menemukan pekerjaan yang memuaskan dengan keterampilan yang saat ini Anda kenal.

Ingin menjelaskan alasan saya: Saya bukan anti-C ++ 11. Hanya dengan mengatakan Anda bisa menggeneralisasi pertanyaan OP ke "Mengapa saya harus belajar X". Saya tidak pernah belajar ML, skema, atau haskell karena saya punya pekerjaan dengan C dan C ++. Saya yakin bahasa-bahasa itu berguna bagi seseorang, tetapi mereka tidak bermanfaat untuk saya pelajari saat ini. Jika seseorang menawarkan saya banyak uang untuk diprogram dalam ML, saya mungkin mencoba mempelajarinya.

Timmah
sumber
3
Jika Anda seorang pengembang "C / C ++", dan jika bos Anda memberi tahu Anda untuk menggunakan C ++ 11, tidakkah Anda hanya perlu melanjutkan dan menambahkannya ke gudang senjata Anda? Saya setuju bahwa Anda tidak harus menghabiskan seluruh waktu Anda belajar bahasa hanya untuk mempelajari mereka, tetapi ketika bos Anda berkata, "Pelajari ini", mungkin ide yang baik untuk terus maju dan mempelajarinya. Itu juga membuat Anda lebih mudah dipasarkan, daripada harus menjelaskan pada aplikasi Anda berikutnya bahwa Anda dipecat karena pembangkangan.
Panzercrisis
Haskell ... Lucu, karena perlahan-lahan dimasukkannya lambdas di C ++. : P
rbaleksandar
85

Itu mudah. C ++ 11 membuat kode secara dramatis lebih mudah, lebih bersih untuk ditulis, dan lebih cepat.

nullptradalah peningkatan VAST dari yang lama 0. Jenisnya aman dan tidak berkonversi saat seharusnya tidak 0. Ini adalah hal yang baik yang nullptrtidak akan dikonversi menjadi int. Tidak masuk akal untuk itu terjadi sama sekali. Tahukah Anda apa yang ditemukan oleh Komite C ++ ketika mereka mencoba mempertimbangkan #define NULL nullptr? Hal-hal seperti char c = NULL;. Seberapa mengerikan itu? Satu-satunya alasan ada pengecualian di sini adalah karena booldianggap sebagai tipe integral, yang cukup salah- tapi itu ada di C ++ sebelumnya, dan di C. Fakta bahwa nullptrtidak mengkonversi adalah baik , itu hebat dan Anda harus menyukainya.

Atau bagaimana dengan menilai referensi dan template variadic? Lebih cepat, lebih banyak kode generik. Itu kemenangan total di sana.

Bagaimana dengan perbaikan perpustakaan? Hal-hal seperti function, unique_ptrdan shared_ptrjauh lebih baik daripada apa yang ada di sana sebelumnya, tidak mungkin untuk berpendapat bahwa cara C ++ 03 lebih baik.

#define adding_func(x, y) ((x)+(y))

Bahkan tidak sederajat. Makro buruk karena enam miliar alasan. Saya tidak akan mengutip semuanya di sini, tetapi diketahui bahwa makro harus dihindari untuk hampir semua tujuan yang mungkin dapat dihindari. Apa yang akan kamu lakukan saat itu?

#define add_twice(x) (x + x)

Oh, tunggu, saya harap Anda tidak menambah atau sesuatu x. Versi fungsi templat yang benar-benar kebal terhadap. Saya juga berharap Anda tidak menghargai ruang nama , misalnya.

Kemudian Anda membuka diri Anda ke dunia perilaku tidak terdefinisi untuk menggunakan variabel eksternal yang cakupannya sudah selesai.

Dalam API fungsional, misalnya algoritma STL, maka referensi baik-baik saja. Jika ini adalah panggilan balik yang disimpan, maka Anda perlu menangkap berdasarkan nilai. Dokumentasi apa pun yang Anda miliki tentang fungsi harus secara jelas menunjukkan mana yang perlu. Fakta bahwa kode ditulis dalam lambda tidak relevan dengan masalah merujuk ke variabel lokal - jika Anda melewati objek fungsi biasa, maka Anda akan memiliki masalah yang sama persis. Dan itu bukan masalah. Sama sekali. Karena itu sudah jelas ketika Anda bisa dan tidak bisa merujuk ke variabel lokal.

Ambil C misalnya. Setelah bertahun-tahun, masih banyak orang yang belajar dan menulis kode dalam C. Mengapa?

Ada banyak orang yang tidak menyikat gigi di pagi hari. Ada banyak pembunuh, pemerkosa, dan pelacur. Dan para politisi. Orang yang bunuh diri. Apakah Anda berpendapat bahwa itu membuat kegiatan ini baik atau bermanfaat? Tentu saja tidak. Ini adalah kekeliruan logis bahwa hanya karena seseorang melakukannya, maka itu pasti baik atau bermanfaat.

C masih ditulis karena tiga alasan: karena C ++ adalah pelacur untuk diimplementasikan, misalnya pada mode embedded atau kernel; karena basis kode lama ditulis dalam C dan akan membutuhkan biaya terlalu banyak untuk memutakhirkan, walaupun itu pun dipertanyakan karena C ++ sangat baik interop; dan karena orang yang menulisnya tidak tahu cara memprogram. Itu dia. Tidak ada alasan lain untuk menulis C.

Jika Anda menggunakan C atau gaya lama C ++, Anda tidak akan menemukan banyak pengecualian.

Bagaimana dengan array gaya C yang menyedihkan, untuk contoh sederhana? Jumlah orang yang tidak bisa mendapatkan array dan pointer langsung di kepala mereka tidak sopan. Belum lagi fakta bahwa perpustakaan C Standard sangat tidak aman.

Argumen inti Anda penuh dengan kesalahan logika dan kesalahpahaman.

DeadMG
sumber
7
> Fakta bahwa nullptr tidak mengonversi itu bagus, itu bagus dan Anda harus menyukainya. OK pendapat Anda, tapi tenanglah sejenak tentang apa yang harus CINTA orang lain, tolong ... Langkah selanjutnya adalah C ++ pengacara Talibanism!
Emilio Garavaglia
5
Saya pikir bagian selanjutnya dari jawaban Anda lebih dari mengapa C ++ harus lebih disukai daripada C. Itu tidak mungkin. "Perpustakaan tidak aman" - bagaimana mungkin ini menjawab pertanyaan? Maksud saya tentu saja orang harus mempelajari fitur-fitur baru yang ditawarkan C ++ 11, tetapi C dan C ++ TIDAK dimaksudkan untuk melakukan hal yang sama. Jika C ++ adalah pelacur untuk diimplementasikan pada level rendah, begitu juga C #, Java, Python dan yang lainnya karena mereka tidak dimaksudkan untuk menjalankan yang rendah. Hanya karena C ++ mengkompilasi ke kode asli tidak berarti Anda dapat menggunakan OO dan meronta-ronta halaman yang terkait dengannya untuk kode level kernel yang kritis.
yati sagade
11
@ Shahbaz, jelas Anda harus belajar sedikit lebih banyak tentang bahasa pemrograman (misalnya, sistem tipe, pelingkupan leksikal, dll.), Semua komentar Anda sepenuhnya tidak sinkron. Mulailah dengan buku ini: amazon.com/Theories-Programming-Languages-John-Reynolds/dp/…
SK-logic
5
@yati: C ++ memiliki sistem modul yang sama dengan C. Fungsi anggota diimplementasikan sebagai fungsi C biasa yang lama. Fungsi virtual diimplementasikan sama dengan memuat fungsi dari DLL. Tidak ada halaman meronta-ronta tentang itu. Dan ya, itu pasti berlaku. Sebagai permulaan, keyakinan Anda bahwa Unix adalah yang terbaik adalah subjektif. Ini pangsa pasar 5% menyarankan sebaliknya. Dan kedua, bahkan jika saya mengagumi Unix tanpa akhir, satu contoh tidak akan menetapkan tren. Hal yang sama berlaku untuk contoh-contoh lain yang Anda kutip. Contoh apa? Mereka tidak ada artinya. C ++ sama cocok untuk prosedur seperti C.
DeadMG
8
@yatisagade C ++ adalah bahasa multi-paradigma yang tidak menegakkan fungsi virtual untuk semuanya, dan program saya di C ++ serupa. Bagian-bagiannya menggunakan desain berorientasi objek, bagian-bagiannya fungsional, dll., Tergantung pada pemecahan apa yang terbaik untuk sub-masalah tertentu. Saya menghargai C ++ untuk menambahkan gaya berorientasi objek, dan saya menghargai C ++ 11 untuk memperluas dukungan untuk pemrograman fungsional.
David Stone
29

C ++ 11 bukan bahasa baru; itu hanya ekstensi / modifikasi dari C ++ yang sudah Anda ketahui. C ++ 11 sama seperti bahasa pemrograman lainnya yang terdiri dari fitur. Banyak dari mereka ada di sana dari sebelumnya, beberapa dari mereka baru. Tetapi pertanyaan Anda sebenarnya adalah, haruskah saya mempelajari semua fitur bahasa (dalam hal ini C ++ 11), atau hanya membiasakan diri dengan 90% saja?

IMO bahkan jika Anda tidak menggunakan semua bahasa, Anda setidaknya harus membaca apa yang dilakukan fitur baru untuk Anda. Banyak dari mereka diperkenalkan untuk membuat kode pustaka / kerangka kerja (terutama templat) lebih mudah untuk ditulis (misalnya, sebelum C ++ 11 penerusan yang sempurna tidak mungkin), tetapi jika Anda tidak pernah membutuhkan fitur tersebut sebelumnya, kemungkinan Anda menang perhatikan bahwa fitur ini ditambahkan dalam C ++ 11.

Di sisi lain, jika Anda sebelumnya mencoba-coba menulis perpustakaan / kode inti yang meniru beberapa fungsi STL / Meningkatkan dan menemukan diri Anda dibatasi oleh bahasa karena Anda datang 95% untuk memiliki solusi yang sangat keren, elegan tapi kemudian Anda dihentikan karena ternyata bahasa tidak mendukung apa yang Anda inginkan, Anda akan menyadari kekuatan C ++ 11 yang benar-benar luar biasa. Sejak tim kami memutakhirkan ke VS2010 (dan kami telah menemukan Peningkatan dalam proses), saya dapat melakukan beberapa kode yang luar biasa, yang tidak mungkin dilakukan sebelum hal-hal seperti referensi r-value dan penerusan parameter templat.

Juga hal-hal seperti lambda mungkin terlihat asing, tetapi mereka tidak memperkenalkan konstruksi baru. Alih-alih mereka membuat apa yang kita miliki sebelumnya sehingga lebih mudah untuk menulis. Sebelumnya setiap fungsi lambda harus menjadi kelas yang terpisah. Sekarang hanya {... kode ...}. Suka.

Kuncinya adalah jangan melihat fitur-fitur ini dan pikirkan betapa menakutkan daftar itu. Sebaliknya, gunakan C ++ seperti biasa dan ketika Anda menemukan beberapa skenario di mana fitur-fitur C ++ 11 baru ini sangat berguna (lebih dari 90% orang tidak akan pernah sampai ke titik itu), Anda akan sangat senang bahwa ekstensi untuk bahasa itu dilakukan. Untuk saat ini, saya sarankan Anda cukup belajar tentang bahasa tersebut untuk mengetahui apa yang ada di sana, belum tentu cara menggunakannya.

DXM
sumber
7
@ Shahbaz - Saya pikir Anda masih kehilangan niat mengapa fungsi tanpa nama ditambahkan. Dan "menggunakan variabel tanpa menganggapnya sebagai input" disebut penutupan dan tersedia dalam banyak bahasa tingkat tinggi lainnya. Jika Anda menulis banyak kode templat dengan objek functor, dengan C ++ 11 Anda akan menyambut fungsi lambda dengan tangan terbuka. Pikirkan seperti ini ... ketika kompiler membuat kode mesin, tidak ada yang namanya fungsi templat atau kelas. Mereka semua "dipakai" untuk membuat kelas / fungsi konkret sebelum titik itu. Lambdas adalah hal yang sama ketika datang ke stateful ...
DXM
5
... functors. Alih-alih membuat orang menulis satu ton kode, satu untuk setiap jenis functor dan setiap elemen penutupan yang ingin Anda lewati, C ++ 11 memungkinkan Anda untuk menentukan sintaks cara pintas dan itu akan secara otomatis membuat instantiate seluruh kelas functor internal seperti itu instantiates template. Sekali lagi, perlu diingat bahwa sebagian besar fitur ini tidak akan digunakan di 98% dari kode tingkat aplikasi, tetapi mereka ditambahkan untuk membuat perpustakaan seperti STL / Boost yang jauh lebih kuat dan lebih mudah untuk menerapkan / memelihara / debug
DXM
10
@ Shahbaz: Oke, Anda tidak mengerti fungsi atau penutupan lambda. Itu masuk akal. Fakta bahwa mereka digunakan dalam banyak bahasa yang berbeda harus menunjukkan bahwa mereka berguna, apakah Anda memahaminya atau tidak, dan bahwa Anda harus memahaminya sebelum terlalu banyak mengkritik mereka.
David Thornley
8
@ Shahbaz: Jika Anda berpikir penutupan mirip dengan variabel global, Anda tidak mengerti penutupan. (Petunjuk: variabel global menyebabkan masalah karena setiap fungsi dapat memodifikasinya.) Jika Anda memahami konsep lambdas, bukan implementasinya, Anda tidak akan mengaitkannya dengan kebingungan kelas vs kode. Segala sesuatu dalam Standar C ++ ada untuk alasan yang meyakinkan bagi sejumlah besar orang cerdas. Anda tidak harus setuju dengan alasannya, tetapi tanpa mengetahuinya Anda mengkritik karena ketidaktahuan.
David Thornley
6
@ Shahbaz, sama sekali tidak ada kesamaan antara penutupan dan global, Anda benar-benar kehilangan intinya. Baca ini: en.wikipedia.org/wiki/Lambda_calculus dan meledakkan otak Anda: en.wikipedia.org/wiki/Combinatory_logic
SK-logic
18

Apakah begitu sulit untuk menulis suatu fungsi, sehingga Anda harus menulis konten fungsi sesuai dengan kode, selain tidak memberikan nama?

Ketika Anda melakukan itu, Anda gulir ke atas, atau buka file sumber baru dan tambahkan definisi fungsi di sana. Maka Anda harus kembali dan melanjutkan apa yang sedang Anda kerjakan, yang mengalihkan Anda ke tingkat tertentu.

Selain itu, ketika orang lain membaca Anda kode lambda mungkin lebih banyak mendokumentasikan diri dalam beberapa kasus, daripada mengatakan "Oh, apa fungsi ini lakukan?" dan melompat ke deklarasi Anda hanya bisa melihat apa yang dilakukannya di tempatnya sendiri.

Ada obrolan yang bagus dari Herb Sutter tentang lambdas, mungkin dia bisa meyakinkan Anda lebih baik:

http://channel9.msdn.com/events/PDC/PDC10/FT13

Nah, mengapa Anda tidak menulis kode saja di sana alih-alih menjadikannya fungsi lambda?

Karena Anda tidak dapat melakukannya ketika Anda menggunakan algoritma STL, atau fungsi apa pun yang Anda gunakan yang mengharuskan Anda untuk melewati suatu fungsi.

#define Menambahkan_fungsi (x, y) ((x) + (y))

Tidak ada cara untuk membenarkan penggunaan ini daripada lambda, Anda tidak dapat mengisi kode Anda dengan makro di mana-mana. Makro dan fungsi memiliki tujuan yang berbeda, dan satu, secara umum, bukan pengganti yang lain.

template<class Lhs, class Rhs>
auto adding_func(const Lhs &lhs, const Rhs &rhs)
                -> decltype(lhs+rhs) {return lhs + rhs;}

Saya setuju, ini jelek. Namun saya ingat diri saya berkata "mengapa saya harus mencari tahu jenis ekspresi ini meskipun kompiler dapat menyimpulkan ini?" dalam banyak kasus. Ini mungkin banyak membantu pada saat-saat itu.

Untuk menyimpulkan:

Meskipun fitur-fitur baru dari C ++ 11 tampak jelek di sintaksis mereka, saya pikir kita bisa terbiasa dengannya dalam waktu singkat. Setiap konstruksi bahasa baru pada awalnya sulit dipelajari; bayangkan pertama kali Anda belajar menulis seluruh kelas: Menempatkan deklarasi dalam file header, tidak melupakan titik koma tambahan di akhir, meletakkan definisi dalam file sumber, termasuk file header sambil memastikan bahwa ia memiliki penjaga untuk mencegah beberapa inklusi, tidak melupakan operator resolusi lingkup dalam deklarasi fungsi anggota dan seterusnya ...

Tapi saya cukup yakin bahwa setelah menulis beberapa kelas Anda terbiasa, dan Anda tidak memikirkan kerumitan proses ini: Karena Anda tahu bahwa kelas membuat pekerjaan Anda sebagai programmer jauh lebih mudah, dan utilitas yang Anda gunakan penghasilan dari konstruk baru ini jauh lebih besar daripada kehilangan utilitas selama Anda mencoba mempelajari bahasa . Saya pikir ini bisa menjadi alasan mengapa seseorang harus mencoba untuk belajar, atau menggunakan C ++ 11 dengan cara yang sama.

keras dan jelas
sumber
Argumen tentang mendokumentasikan diri dan kurang menggulir dll, saya cukup yakin argumen yang berlawanan seperti "kode berantakan", "membatasi akses" dll pernah digunakan untuk berdebat mengapa fungsi di luar kelas harus dilarang. Saya pikir orang perlu lebih berpengalaman untuk memutuskan mana yang lebih baik. Menurut saya ini adalah eksperimen yang gagal atau desain yang buruk. Saya lebih yakin untuk tidak menjadi tikus percobaan dalam percobaan ini.
Shahbaz
Tentang sintaks yang terlihat jelek, ambil dua contoh ini: bool is_alive;dan bool thisSpecialObjectOfMineIsAlive;. Keduanya melakukan hal yang sama, tetapi yang kedua terlihat sangat jelek. Mengapa? Karena saya secara keliru berpikir memasukkan lebih banyak info membuatnya lebih jelas, tetapi telah melakukan yang sebaliknya. Ini kesepakatan yang sama di sini, Stroustrup berarti bagus dengan memberi kita fitur, tetapi dia tidak membuatnya terlihat bagus. Bagi saya ini menunjukkan desain yang buruk.
Shahbaz
3
tampan! = baik, dan buruk! = buruk.
DeadMG
@ Shahbaz: Saya pikir lambdas adalah konsep yang hebat (dan telah ada selama bertahun-tahun dalam bahasa seperti Lisp). Saya sering menggunakannya di Haskell. Saya kurang yakin bahwa mereka cocok dalam bahasa seperti C ++, Java, dll. Mereka merasa agak ketinggalan jaman bagi saya: sesuatu yang ditambahkan kemudian karena lambda telah menjadi populer. Mengapa mereka tidak diperkenalkan dalam bahasa-bahasa ini sejak awal? Apakah Stroustrup dan Goslin tidak pernah mendengar tentang Lisp?
Giorgio
8

Sebenarnya OP memiliki beberapa poin, hingga sebagian besar jawabannya. Tetapi mereka "jauh" dalam penglihatan. C ++ (termasuk subset C) memiliki sejarah panjang di mana sejumlah fitur telah ditambahkan sepanjang waktu, beberapa dari mereka menggunakan lebih atau kurang sering dan - melalui penggunaan dan kesalahan teir - disempurnakan menjadi orang lain dan orang lain.

Kadang-kadang terjadi bahwa, setelah memperkenalkan fitur baru, yang lama diperlukan lagi, atau terasa bertentangan dengannya. Bahasa "bersih" harus konsisten dengan dirinya sendiri, dan fitur yang tidak diperlukan lagi harus dihapus.

Tetapi menambahkan tidak menghancurkan apa pun. Menghapus (atau mengubah) memecah kode yang sudah ada yang masih dalam produksi, jadi fitur apa pun yang Anda tambahkan, Anda harus berhati-hati untuk tidak memecahkan kode yang ada (khususnya, jangan memecahnya diam - diam , membuatnya melakukan hal-hal yang berbeda seperti yang dimaksudkan ).

Apakah Anda harus mempelajari semua itu? Ya, karena semua fitur -adalah yang baik atau buruk, cepat atau lambat- digunakan. Apakah ini hal yang baik untuk "kualitas" bahasa (mengakui ada ukuran objektif untuk itu) adalah cerita lain: berapa lama kompatibilitas harus dipertahankan? sulit untuk menemukan jawaban, ketika seseorang mengatakan 3 tahun dan beberapa lainnya mengatakan 50.

Alternatif untuk menjaga C ++ lebih "biasa" adalah ... hancurkan lebih sering, dengan restart awal. Tapi itu tidak akan menjadi C ++ lagi.

Ada upaya untuk melakukan itu juga (pikirkan untuk D, misalnya: jauh lebih ortogonal daripada C ++ (bahkan 11) sebenarnya), tetapi seberapa populerkah mereka? Salah satu alasan sulitnya mendapatkan momentum adalah ketidakcocokan dengan banyak kode yang ada yang masih harus dijalankan.

C ++ 11, bagi saya, jelas merupakan kompromi antara kebutuhan baru dan kompatibilitas. Itu menghasilkan "kekacauan" tertentu dari spesifikasi dan implementasinya. Sampai biaya "kekacauan" itu kurang dari biaya ketidakcocokan ... Anda harus pergi dengan kompromi itu.

Jika Anda tidak bisa lagi menoleransi itu, ... lebih baik mempertimbangkan bahasa lain yang lebih muda. C ++ tidak bisa disederhanakan dalam arti itu. Tidak pada usia ini.

Emilio Garavaglia
sumber
Saya juga setuju. Dan sebagai seorang pengembang saya merasa sangat mengganggu memiliki bahasa yang berubah setiap saat (bahwa saya harus belajar berulang kali). Jika Anda mengembangkan bahasa baru Anda harus membuat awal baru dan menggunakan nama yang berbeda. Jika Anda ingin bekerja sama dengan kode lawas, ada kompilasi terpisah untuk itu. Jadi saya benar-benar tidak mengerti kebijakan mengubah bahasa yang ada dengan memasukkan fitur-fitur terbaru yang telah menjadi mode. Seperti seseorang berkata: pengembangan lebih lanjut tidak secara otomatis menyiratkan kemajuan.
Giorgio
"C ++ tidak bisa disederhanakan dalam pengertian itu. Tidak pada usia ini.": Mengapa bahasa pemrograman lain (mis. C, Ada, ...) tidak mengikuti jalur yang sama? Mungkin karena mereka memiliki ceruk aplikasi sendiri dan mereka tidak diharapkan menjadi alat untuk semua area aplikasi yang mungkin.
Giorgio
@giorgio: ya ... Anda mungkin benar dalam arti "pragmatis". Tetapi secara teori ... Saya ingat beberapa hari yang baik di mana pascal adalah "bahasa referensi pengajaran" dan ada adalah "semuanya bahasa pemrograman wannabe".
Emilio Garavaglia
Saya juga belajar pemrograman dalam Pascal. Sejauh yang saya tahu Ada mengalami beberapa revisi tetapi desain dasar bahasa tidak ditumbangkan. Sama dengan C dan Pascal. Jika seseorang ingin mengembangkan bahasa yang benar-benar baru, ia harus cukup berani untuk membuat potongan yang jelas dan memulai sesuatu yang baru, seperti D, Java, C #. Masalah saya dengan jalur saat ini C ++ adalah apakah itu (tidak perlu) menjadi terlalu kompleks. Jika prinsip-prinsip KISS dan YAGNI berlaku untuk desain perangkat lunak, mengapa mereka tidak berlaku untuk desain bahasa pemrograman juga?
Giorgio
@Iorgio: oh ... itu berlaku ... persis seperti yang Anda katakan. Jika Anda berpikir C # atau D melakukan pilihan yang lebih baik daripada C "rebus" (interpretasi saya tentang perasaan Anda), gunakan saja alih-alih C ++. Saat waktu bergerak pada C ++ perlahan akan mati. Saat ini, saya melihat C ++ 11 memberi peluang baru pada "rebus" C ++ 03, dan D dengan masih ada sesuatu yang hilang untuk memecahkan penghalang awal. Kepentingan ekonomi dan korporasi juga berperan dalam bagaimana pembangunan dibiayai dan didorong. Anda benar secara teori, tetapi dunia nyata lebih kompleks.
Emilio Garavaglia
7

Bahkan jika Anda memutuskan untuk mengabaikan fitur-fitur C ++ 11 yang baru, Anda masih akan mendapat manfaat darinya karena C ++ Standard Library akan menggunakannya. Sebagai contoh, di C ++ 98 memiliki variabel tipe vector<string>berpotensi bencana kinerja karena jumlah salinan yang perlu dibuat ketika vektor tumbuh. Dengan C ++ 11 move constructor, ini bukan masalah. Bahkan, saya berharap C ++ 11 memberi kami lebih banyak fitur baru, tidak kurang - terutama di Perpustakaan Standar.

Nemanja Trifunovic
sumber
6

Setelah bertahun-tahun, masih banyak orang yang belajar dan menulis kode dalam C. Mengapa? Karena bahasanya bagus.

Pertama, sebagian besar siswa saat ini belajar Java atau. NET, bukan C. Kedua, orang masih menggunakan C bukan hanya karena kelebihannya sebagai bahasa, tetapi terutama karena ada sejumlah besar perangkat lunak yang ada ditulis dalam C yang perlu dipertahankan dan diperluas, dan karena dalam banyak kasus (misalnya platform yang disematkan), hanya ada kompiler C. Kebetulan, ini adalah beberapa alasan mengapa orang masih menulis COBOL.

Sangat jarang bagi seorang programmer di industri untuk mulai bekerja pada proyek baru yang tidak terikat pada basis kode yang ada, dan untuk terus bekerja sendiri. Jadi, alasan untuk mempelajari C ++ 11 adalah Anda cenderung harus berurusan dengan kode yang ditulis oleh orang lain, yang menggunakan fitur-fitur baru. Juga, fitur yang ditambahkan ditambahkan karena suatu alasan. Setelah Anda mempelajarinya dan menggunakannya, Anda mungkin akan menghargainya.

Dima
sumber
Anda mengutip kalimat saya tidak lengkap. Seperti yang saya katakan di kalimat setelahnya, goodartinya mengikuti aturan desain bahasa pemrograman yang baik. Saya tidak tahu di mana Anda belajar, tetapi saya tahu dari 4 atau 5 negara dan mereka semua mulai belajar pemrograman dengan C. Seperti yang saya katakan, dengan C, tidak ada pengecualian (sesuatu yang berlawanan di Jawa, Anda hampir tidak bisa temukan konstruk yang tidak memiliki pengecualian).
Shahbaz
1
@ Shahbaz: Saya mengutip kalimat lengkap. Anda membuat hubungan sebab akibat, dan saya mengatakan bahwa itu paling tidak lengkap. Syukurlah, saya tidak belajar lagi. :) Saya sudah cukup banyak melakukan itu. Saya tinggal di AS, dan ketika saya pergi ke perguruan tinggi (lebih dari 15 tahun yang lalu) C adalah bahasa pengantar. Namun, saat ini sebagian besar sekolah AS mulai dengan Jawa, dan tidak banyak programmer muda yang tahu C.
Dima
5
@ Shahbaz: Saya benar-benar tidak melihat masalah dengan aturan bahasa yang memiliki pengecualian. Ya, C adalah bahasa yang jauh lebih sederhana daripada C ++. Di sisi lain, C ++ membuatnya lebih mudah untuk menulis kode yang lebih sederhana. Untuk menulis kode yang lebih sederhana, Anda memerlukan lebih banyak fitur bahasa. Itu membuat bahasa lebih kompleks. Saya, misalnya, menyukai hal-hal seperti kelas, referensi, RAII, templat, konstruktor, destruktor, pengecualian, dan ruang nama. Tetapi Anda mengatakan pertanyaan Anda bukan tentang C vs C ++, jadi saya tidak menulis tentang itu dalam jawabannya.
Dima
5
  • Majelis dibuat karena orang tidak suka menulis kode mesin
  • C dibuat karena orang tidak suka menulis rakitan
  • C ++ dibuat karena orang tidak suka menulis C
  • C ++ 11 dibuat karena orang tidak suka menulis C ++

Anda akan sampai pada suatu titik dalam karir C ++ Anda di mana Anda berkata pada diri sendiri, "Saya yakin para functors lebih sederhana," atau "Mengapa NULL adalah int?" dan kemudian Anda akan mengerti C ++ 11.

Pubby
sumber
Semua bahasa dibuat karena seseorang tidak menyukai yang ada. Itu tidak membuat mereka baik.
Shahbaz
Saya tidak mengatakan NULLharus menjadi int. Seharusnya tidak. Apa yang saya anggap tidak tepat adalah untuk memperkenalkan konstruksi dalam bahasa yang memecahkan ini, tetapi memperkenalkan pengecualian. Mereka seharusnya bisa melakukan hal yang sama dengan cara yang lebih baik.
Shahbaz
2
"C ++ 11 dibuat karena orang tidak suka menulis C ++": jika mereka tidak suka menulis C ++, mengapa C ++ adalah subset dari C ++ 11?
Giorgio
1
Seharusnya: C # dan Java dibuat karena orang tidak suka menulis C ++.
Calmarius
4

Belajar selalu bermanfaat. Pengetahuan adalah kekuatan.

Itulah jawabannya, pada dasarnya. Yang lainnya hanyalah perincian tentang bagaimana tepatnya Anda dapat memperoleh manfaat darinya dan kekuatan apa yang Anda miliki dengan mengetahuinya, dan mereka sangat banyak sehingga setiap penghitungan tidak lengkap.

Salah satu contoh adalah pertanyaan Anda sendiri. Anda bahkan tidak akan bisa bertanya tanpa belajar sedikit pun.

Dan seperti yang saya komentari - perhatian sebenarnya bukanlah mengapa harus belajar, tetapi mengapa harus digunakan . Dan itu pertanyaan yang sama sekali berbeda.

littleadv
sumber
4

Anda harus belajar C ++ 11 karena fitur yang ditambahkan memungkinkan Anda untuk menulis kode yang lebih baik. Beberapa orang telah menyebutkan jenis keamanan pointer NULL dan lambdas, yang sangat bagus. Tapi saya ingin menarik perhatian pada apa yang saya pikir adalah perubahan paling dramatis dalam C ++ 11, terutama di lingkungan produksi besar: pindahkan semantik.

C ++ 11 mendukung gagasan terpisah tentang 'bergerak' dan 'menyalin'. Dalam C ++ reguler, kami hanya memiliki operator = yang pada dasarnya melakukan keduanya. Tapi sungguh, kami mengekspresikan dua ide terpisah dengan satu operator, yang berbahaya.

Contoh paling jelas tentang di mana ini berguna adalah unique_ptr baru. Ini memiliki semua fitur terbaik dari auto_ptr lama dan scoped_ptr. Misalkan kita ingin memiliki pointer yang dijamin menjadi satu-satunya pointer yang menunjuk ke suatu objek. Bagaimana cara kita menangani a = b? Nah, sebelumnya, kami macet, Anda bisa melarangnya sepenuhnya (seperti scoped_ptr), atau kita bisa melakukan apa yang auto_ptr lakukan di mana a = b mencuri kepemilikan dari b. Perilaku auto_ptr ini sangat membingungkan karena a = b benar-benar berubah b. unique_ptr menangani ini: a = b tidak diizinkan, tetapi Anda memiliki = std :: move (b) untuk mencuri kepemilikan. Bagaimana ini berguna? Di mana, ada versi terpisah (kelebihan beban) dari swap yang menggunakan semantik pindah daripada menyalin semantik. Ini berarti bahwa unique_ptr dapat ditukar, tidak ada masalah. Ini berarti unique_ptr, tidak seperti auto_ptr, aman untuk digunakan dalam wadah dan kemudian ucapkan semacam. unique_ptr pada dasarnya adalah semua dan mengakhiri semua manajemen memori yang aman ketika Anda tidak memerlukan banyak pointer pada objek yang sama.

Contoh bagus lainnya: misalkan Anda memiliki objek yang tidak dapat disalin. Ini berguna dalam sejumlah situasi. Anda tidak pernah dapat mengembalikan objek ini dari suatu fungsi, karena ketika fungsi berakhir itu menyalin apa pun yang Anda kembalikan. Hal yang ironis adalah bahwa biasanya kompiler benar-benar mengoptimalkan ini (yaitu tidak ada yang benar-benar disalin pada akhirnya, nilai pengembalian dibuat pada alamat penugasan akhirnya). Tetapi ini tidak ada hubungannya dengan mengapa kita membuatnya tidak bisa disalin; kembali dari suatu fungsi sebenarnya hanya memindahkan objek dari dalam lingkup fungsi ke luar. Anda sekarang dapat menulis objek yang tidak dapat disalin tetapi ADALAH bergerak, dan objek ini dapat dikembalikan dari fungsi.

Memindahkan semantik membuatnya lebih mudah untuk menulis kode yang tidak akan bocor dan aman utasnya.

Nir Friedman
sumber
Dan juga, omong-omong, efisien.
Nir Friedman