Apakah ada sumber daya tentang cara mengidentifikasi masalah yang paling baik diselesaikan dengan template?

8

Saya memutuskan untuk meningkatkan pengetahuan saya dalam meta-programming template. Saya tahu sintaks dan aturan dan bermain dengan banyak contoh dari sumber online.

Saya mengerti betapa kuatnya templat dan berapa banyak waktu kompilasi optimasi yang dapat mereka berikan, tetapi saya masih tidak bisa "berpikir dalam templat", saya sepertinya tidak tahu sendiri apakah masalah tertentu dapat diselesaikan dengan templat dan jika bisa, bagaimana mengadaptasi masalah itu ke templat.

Apakah ada beberapa sumber atau buku daring yang mengajarkan cara mengidentifikasi masalah yang paling baik diselesaikan dengan templat dan bagaimana mengadaptasi masalah itu?

getah
sumber
5
Jika semua yang Anda miliki adalah palu, semuanya terlihat seperti paku ;-) Jangan mencoba terlalu banyak untuk berpikir tentang menggunakan templat untuk semua dan segalanya, setidaknya, tidak jika Anda tidak akan merancang versi selanjutnya dari standar C ++ Perpustakaan.
Doc Brown
Anda benar, saya tidak akan melihat kode produksi dan mencoba menyesuaikan TMP di mana-mana heh: p ini hanya untuk pembelajaran pribadi, karena saya tahu betapa kuatnya mereka dan saya suka bagaimana beberapa programmer C ++ yang hebat (seperti STL yang bekerja pada MS) dapat menerapkan TMP begitu cepat untuk masalah yang diberikan dan tampak sangat menakjubkan. STL memiliki beberapa video di channel9 yang benar-benar membuat saya terkesan tentang TMP itu sebabnya saya ingin belajar lebih banyak.
getah

Jawaban:

8

Buku:

Desain C ++ modern

Pemrograman Template C ++

Menjadi akrab dengan rekursi dan pemrograman fungsional adalah nilai tambah yang besar, karena itulah yang melibatkan banyak tmp. Ini turing lengkap dan pada dasarnya segala sesuatu mungkin, meskipun biasanya bermuara pada penerapan fungsi murni untuk konstanta atau menghasilkan jenis dari tipe lain.

Peringatan: tmp adalah monster jelek yang mengubah kode yang bagus menjadi spaghetti. Semakin banyak Anda menggunakannya, semakin sedikit Anda akan menyukai C ++. Itu adalah hal yang jahat.

Pubby
sumber
1
+1 untuk "tmp adalah monster jelek". C ++ bagus dalam beberapa hal, sama seperti bahasa apa pun; tapi metaprogramming bukan salah satunya.
Jon Purdy
"Desain C ++ modern" adalah klasik, tetapi IIRC lebih banyak tentang menerapkan hal-hal menggunakan trik templat yang pintar daripada tentang memutuskan apa yang harus diimplementasikan sebagai templat. Tidak. 1 prinsip untuk itu mungkin "tidak" - alasan paling umum untuk memerlukan templat sudah dicakup oleh pustaka standar (esp. C ++ 11), Boost, dan pustaka yang sudah ada lainnya, jadi perlu menggulung Anda sendiri sebenarnya bukan hal sehari-hari.
Steve314
Metaprogramming Template C ++ hanyalah panduan pengguna dari bagian boost. Tidak mengajarkan Anda banyak tentang memilih aplikasi yang terkait atau tentang bagaimana melakukan hal serupa di C ++.
Pemrogram
6

Pelajari Haskell atau bahasa fungsional murni lainnya (Lisp, Skema, OCaml, beberapa, Anda dapat menemukan lebih banyak di Wikipedia ).

Mempertimbangkan Haskell, Anda dapat menemukan informasi lebih lanjut tentang fasilitas pemrograman ini di sini .

Pemrograman template mengikuti banyak aturan yang sama sebenarnya.

Macke
sumber
1
Perhatikan bahwa Haskell memiliki sistem templating sendiri: Template Haskell.
2
@ MatFenwick: Ya. Dan itu masih Haskell, tidak seperti template c ++. :)
Macke
Saya belum bekerja dengan bahasa fungsional sejak skema di perguruan tinggi. bukan karena saya tidak suka, itu hanya tidak pernah memiliki kesempatan untuk bekerja dan jika saya harus menghabiskan waktu luang saya coding atau belajar lebih banyak saya hanya suka belajar sesuatu yang lain (seperti TMP!) :)
sap
@sap: Yah, Anda harus masuk ke mode berpikir yang sama ...
Macke
@sap: Sebenarnya, Skema mungkin merupakan bahasa yang bagus untuk membiasakan diri dengan penyusunan program-waktu. Sistem makronya sangat mampu dan elegan sambil mencapai efek yang mirip dengan template C ++ (saya pikir. Saya belum pernah menggunakan C ++ terlalu banyak).
Tikhon Jelvis
2

Hanya karena Anda dapat melakukan sesuatu dengan template tidak berarti Anda harus melakukannya. Secara praktis, kecuali ketika Anda mendesain Anda berpikir ini adalah pekerjaan yang luar biasa untuk templat, mungkin lebih baik tidak menggunakannya. jika Anda berpikir terlalu banyak dalam template Anda hanya membuat kode abstrak yang sama buruknya dengan fungsi raksasa tunggal.

Ryathal
sumber
terima kasih atas jawabannya, ya saya mengerti itu, saya hanya ingin belajar :)
getah
Saya setuju dengan yang di atas. Dalam kasus di mana saya telah menggunakan templat, biasanya merupakan hasil dari refactoring kode yang ada. Setelah Anda menggunakan kode asli dengan cara baru, templat tersebut akan muncul lebih jelas sebagai penyempurnaan dari yang asli. Lebih sulit untuk mengetahui apakah templat berguna saat melakukan desain sebelum memiliki use case yang diketahui.
Sam Goldberg
2

Perlu diingat bahwa templat menjadi solusi terbaik sangat jarang. Saya hanya mendefinisikan saya sendiri sekali dalam 5 tahun terakhir, dan rekan-rekan saya yang meninjau kode itu belum pernah melakukannya. Kasus-kasus di mana template masuk akal sebagian besar sudah diterapkan di perpustakaan standar.

Untuk pemrograman generik, hal yang harus diperhatikan adalah bahwa Anda menyalin dan menempel fungsi hanya untuk membuat perubahan kecil, seperti dalam konstanta atau tipe, dan tidak dapat menemukan cara bersih untuk menggunakan sesuatu seperti pewarisan atau parameter fungsi untuk menghindari pengulangan dirimu sendiri.

Salah satu cara template yang cukup umum digunakan adalah untuk keamanan tipe, jika Anda memiliki tipe yang berperilaku sama, tetapi untuk alasan apa pun Anda tidak ingin mereka secara tidak sengaja tercampur.

Untuk perhitungan waktu kompilasi menggunakan templat, hal yang harus diperhatikan adalah perhitungan intensif sumber daya di mana semua inputnya diketahui pada waktu kompilasi, tetapi di mana input konstan yang berbeda digunakan di tempat yang berbeda di seluruh kode. Namun, perlu diingat ini akan memperlambat kompilasi Anda setiap saat, jadi seringkali lebih baik hanya mengkode hasil secara manual, jika mereka tidak terlalu sering berubah.

Beberapa advokat menggunakan templat untuk optimasi mikro seperti menghindari pencarian tabel virtual menggunakan polimorfisme statis, atau untuk loop terbuka, tetapi menurut saya kompleksitas biasanya melebihi keuntungan kinerja kecuali kode Anda sangat kritis terhadap kinerja.

Karl Bielefeldt
sumber
terima kasih banyak atas jawabannya, sakit mengingat poin-poin itu dalam pikiran. saya tahu bahwa saya tidak dapat menggunakannya untuk semuanya (seperti seseorang mengatakan sebelumnya, saya tidak bisa mulai melihat semuanya sebagai "kuku") dan jika saya mengerti benar TMP unggul dalam pengembangan perpustakaan (seluruh C ++ tidak), saya melakukan ini hanya untuk belajar dan TIDAK untuk menerapkannya di setiap kode produksi yang saya buat mulai sekarang. dan wow hanya sekali dalam 5 tahun? saya kira itu menunjukkan betapa jarang TMP benar-benar dapat meningkatkan kode.
getah
2

Pada dasarnya, ada beberapa alasan bagus untuk menggunakan templat:

  1. Anda memiliki fungsi atau kelas yang memiliki fungsi yang sama untuk berbagai jenis. Contoh bagus dari penggunaan templat yang baik adalah boost library
  2. Anda ingin menggunakan polimorfisme statis , dan mendapatkan kesalahan kompilasi, bukan kesalahan run-time
  3. Anda ingin mendapatkan perilaku tertentu tergantung pada beberapa parameter statis. Misalnya, boost :: type_traits memberikan contoh yang sangat bagus.
BЈовић
sumber
Terima kasih! ive ciri tipe bekas sebelumnya, benar-benar keren! Apakah enable_if juga sifat tipe? atau hanya "kondisi" SFINAE? karena saya telah menggunakannya sebelumnya (pada review kode) dan sepertinya sangat kuat tetapi saya gagal menerapkannya pada masalah yang berbeda.
getah
@sap Ini adalah tipe sifat, yang dapat diimplementasikan menggunakan SFINAE.
BЈовић
1

Anda pasti harus melihat ke templat di C ++! Ini akan sangat membantu Anda untuk memahami topik seperti Pola Desain dan Pemrograman Generik. Bandingkan mereka dengan apa yang ditawarkan bahasa lain kepada Anda. Tepatnya Anda harus menggunakan template khususnya dalam skenario berikut:

  1. Generalisasi & Penggunaan Kembali Kode
  2. Fleksibilitas
  3. Kendala Waktu & Anggaran
  4. Kurangnya keahlian untuk tugas tertentu

Berikut adalah sumber online yang bagus untuk Anda: http://en.wikipedia.org/wiki/Generic_programming#Templates_in_C.2B.2B

Maxood
sumber
saya tahu apa yang bisa mereka gunakan untuk tidak hanya bagaimana menerapkan pengetahuan itu untuk masalah yang diberikan, tetapi masih bagus terima kasih :)
getah
1

Indikator sederhana kapan templat akan memperbaiki kode Anda, adalah ketika Anda melihat bahwa kode Anda sering mengharuskan Anda untuk melemparkan objek ke jenis yang berbeda. Contoh yang saya temukan di kode Java saya sendiri, yang memicu saya untuk mengonversi tanda tangan metode yang ada ke templat:

    public MsgBase getLastSentMessage(Class<? extends MsgBase> msgBaseClass)

Kode klien saya selalu terlihat seperti ini:

    OrderResponse response = (OrderResponse) getLastSentMessage(OrderResponse.class);

dan setiap kali saya menggunakan metode itu, saya harus memberikan hasilnya ke subclass yang benar dari tipe MsgBase. Tanda tangan metode yang ditingkatkan adalah:

    public <T extends MsgBase> T getLastSentMessage(Class<T> clazz)

Sekarang kode klien adalah:

     OrderResponse response = getLastSentMessage(OrderResponse.class);

Jadi untuk meringkas, jika Anda menemukan diri Anda melakukan banyak casting yang tampaknya tidak perlu, Anda mungkin memiliki kasus yang bagus di mana templat akan membersihkan kode Anda.

Pembaruan: cara yang lebih baik untuk menggeneralisasi pernyataan di atas:

Ketika kelas sumber Anda akan digunakan oleh objek dari berbagai jenis, dan kelas sumber dapat berinteraksi dengan jenis-jenis itu pada tingkat yang lebih tinggi (lebih abstrak), tetapi kelas klien Anda ingin berinteraksi dengan subtipe tertentu, itu adalah kasus untuk menggunakan templat . (Kelas Container / List menjadi contoh yang terkenal).

Sam Goldberg
sumber
ini sangat menarik dan saya tidak pernah berpikir untuk menerapkan TMP seperti itu, hanya menunjukkan bahwa saya benar-benar perlu mempelajarinya lebih baik dan berlatih lebih banyak.
getah
Saya masih mencoba mencari tahu suara turun di sini. Saya menjawab pertanyaan secara langsung dan memberikan contoh konkret tentang kapan Templat muncul dari refactoring. Jadi apa yang salah?
Sam Goldberg
0

Baru hari ini, saya menggunakan templat untuk mengimplementasikan Mesin Negara Hingga untuk lex beberapa input. Template ekspresi adalah alat yang sangat kuat untuk menerapkan konsep kode seperti itu - mereka berjalan seperti C ++ yang dioptimalkan dengan tangan dan sangat cepat, namun sangat generik dan sangat mudah untuk ditulis.

Secara umum, template paling masuk akal ketika menerapkan algoritma generik. Jika Anda tidak menerapkan algoritma generik, mereka tidak masuk akal.

DeadMG
sumber
0

Penggunaan templat yang paling umum adalah sebagai berikut:

std::vector<int> vec;
std::map<int, float> mymap;

Maka contoh umum selanjutnya adalah:

template<class T>
class MyArray {
public:
   virtual T get(int i) const=0;
};

Bersama dengan penggunaan seperti ini:

class ArrayImpl : public MyArray<float> {
public:
     float get(int i) const { }
};

Yang itu menunjukkan bagian penting dari templat, yaitu subtitusi tipe - T diganti dengan tipe float di kedua tempat yang digunakan.

tp1
sumber