Di C ++ 11, apakah ada cara untuk templat fungsi lambda? Atau apakah secara inheren terlalu spesifik untuk dicampuri?
Saya mengerti bahwa saya dapat mendefinisikan kelas templated klasik / functor sebagai gantinya, tetapi pertanyaannya lebih seperti: apakah bahasa mengizinkan templating fungsi lambda?
Jawaban:
UPDATE 2018: C ++ 20 akan datang dengan lambdas templated dan dikonsep. Fitur ini telah diintegrasikan ke dalam konsep standar.
UPDATE 2014: C ++ 14 telah dirilis tahun ini dan sekarang memberikan lambdas Polymorphic dengan sintaks yang sama seperti dalam contoh ini. Beberapa kompiler utama sudah mengimplementasikannya.
Saat berdiri (dalam C ++ 11), sayangnya tidak. Lambdas polymorphic akan sangat baik dalam hal fleksibilitas dan kekuatan.
Alasan asli mereka akhirnya menjadi monomorfik adalah karena konsep. Konsep membuat situasi kode ini sulit:
Dalam templat terbatas Anda hanya bisa memanggil templat terbatas lainnya. (Kalau tidak, kendala tidak dapat diperiksa.) Dapat
foo
memintabar(x)
? Kendala apa yang dimiliki lambda (parameter untuk itu hanyalah templat)?Konsep tidak siap untuk menangani hal semacam ini; itu akan membutuhkan lebih banyak hal seperti
late_check
(di mana konsep tidak diperiksa sampai dipanggil) dan hal-hal lainnya. Simpler hanya membuang semua itu dan menempel pada lambda monomorfik.Namun, dengan menghilangkan konsep dari C ++ 0x, lambdas polimorfik menjadi proposisi sederhana lagi. Namun, saya tidak dapat menemukan proposal untuk itu. :(
sumber
C ++ 11 lambdas tidak dapat di-templated seperti yang dinyatakan dalam jawaban lain tetapi
decltype()
tampaknya membantu ketika menggunakan lambda dalam kelas atau fungsi templated.Cetakan:
Saya telah menemukan teknik ini sangat membantu ketika bekerja dengan kode templated tetapi menyadari itu masih berarti lambdas sendiri tidak dapat di-templated.
sumber
T
akan berfungsi dengan baik di tempatdecltype(t)
dalam contoh ini.Dalam C ++ 11, fungsi lambda tidak dapat di-templated, tetapi dalam versi selanjutnya dari ISO C ++ Standard (sering disebut C ++ 14), fitur ini akan diperkenalkan. [Sumber]
Contoh penggunaan:
Perhatikan bahwa meskipun sintaks menggunakan kata kunci
auto
, pengurangan tipe tidak akan menggunakan aturanauto
pengurangan tipe, tetapi sebaliknya menggunakan aturan pengurangan argumen template. Juga lihat proposal untuk ekspresi lambda generik (dan pembaruan untuk ini).sumber
auto
pengurangan tipe secara khusus didefinisikan sama dengan aturan deduksitemplate
argumen fungsi.Saya sadar bahwa pertanyaan ini tentang C ++ 11. Namun, bagi mereka yang googled dan mendarat di halaman ini, lambda templated sekarang didukung dalam C ++ 14 dan menggunakan nama Generic Lambdas.
[info] Sebagian besar kompiler populer mendukung fitur ini sekarang. Microsoft Visual Studio 2015 mendukung. Dentang mendukung. GCC mendukung.
sumber
Saya bertanya-tanya bagaimana dengan ini:
Saya menggunakan kode serupa seperti ini, untuk menghasilkan template dan bertanya-tanya apakah kompiler akan mengoptimalkan fungsi "pembungkus".
sumber
Lihatlah Boost.Phoenix untuk lambdas polimorfik: http://www.boost.org/doc/libs/1_44_0/libs/spirit/phoenix/doc/html/index.html Tidak memerlukan C ++ 0x, oleh cara :)
sumber
Ada ekstensi gcc yang memungkinkan templat lambda :
dimana
_widgets
astd::tuple< fusion::pair<Key_T, Widget_T>... >
sumber
Saya telah bermain dengan
version 5.0.1
kompilasi dentang terbaru dengan-std=c++17
bendera dan sekarang ada beberapa dukungan yang bagus untuk parameter tipe otomatis untuk lambdas:sumber
Inilah salah satu solusi yang melibatkan membungkus lamba dalam suatu struktur:
Untuk menggunakan lakukan:
Masalah utama dengan ini (selain mengetik tambahan) Anda tidak dapat menanamkan definisi struktur ini di dalam metode lain atau Anda dapatkan (gcc 4.9)
Saya juga mencoba melakukan ini:
Dengan harapan saya bisa menggunakannya seperti ini:
Tapi saya mendapatkan kesalahan kompilator:
Jadi ini tidak bekerja ... tetapi bahkan jika itu mengkompilasi itu akan menjadi penggunaan terbatas karena kita masih harus meletakkan "menggunakan LamdaT" pada ruang lingkup file (karena itu adalah template) yang semacam mengalahkan tujuan dari lambda.
sumber
Saya tidak yakin mengapa tidak ada orang lain yang menyarankan ini, tetapi Anda dapat menulis fungsi templated yang mengembalikan fungsi lambda. Berikut ini memecahkan masalah saya, alasan saya datang ke halaman ini:
Sekarang setiap kali saya ingin fungsi yang mengambil jenis argumen tertentu (misalnya
std::string
), saya hanya mengatakandan sekarang
f("any string")
kembali1.0
.Itulah contoh yang saya maksud dengan "fungsi lambda templated." (Kasus khusus ini digunakan untuk secara otomatis menyediakan fungsi pembobotan inert ketika seseorang tidak ingin menimbang data mereka, apa pun data mereka.)
sumber