Saya mencoba mencari cara untuk mendapatkan alamat fungsi lambda di dalam dirinya sendiri. Berikut ini contoh kode:
[]() {
std::cout << "Address of this lambda function is => " << ????
}();
Saya tahu bahwa saya dapat menangkap lambda dalam sebuah variabel dan mencetak alamatnya, tetapi saya ingin melakukannya ketika fungsi anonim ini dijalankan.
Apakah ada cara yang lebih sederhana untuk melakukannya?
this
.Jawaban:
Itu tidak mungkin secara langsung.
Namun, tangkapan lambda adalah kelas dan alamat objek bertepatan dengan alamat anggota pertamanya. Oleh karena itu, jika Anda menangkap satu objek dengan nilai sebagai tangkapan pertama, alamat tangkapan pertama sesuai dengan alamat objek lambda:
Output:
Atau, Anda dapat membuat lambda pola desain dekorator yang meneruskan referensi ke tangkapan lambda ke operator panggilannya:
sumber
Tidak ada cara untuk secara langsung mendapatkan alamat objek lambda dalam lambda.
Sekarang, seperti yang terjadi ini cukup sering berguna. Penggunaan yang paling umum adalah untuk pengulangan.
The
y_combinator
berasal dari bahasa mana Anda tidak bisa bicara tentang diri Anda sampai Anda mana yang ditetapkan. Ini dapat diimplementasikan dengan mudah di c ++ :sekarang kamu bisa melakukan ini:
Variasi dari ini dapat meliputi:
di mana yang
self
berlalu dapat dipanggil tanpa lewatself
sebagai argumen pertama.Yang kedua cocok dengan kombinator y asli (alias kombinator titik tetap) saya percaya. Yang Anda inginkan tergantung pada apa yang Anda maksud dengan 'alamat lambda'.
sumber
F
bukan tata letak standar, makay_combinator
tidak, maka jaminan waras tidak disediakan.Salah satu cara untuk mengatasi ini, adalah dengan mengganti lambda dengan kelas functor yang ditulis tangan. Itu juga yang pada dasarnya adalah lambda.
Kemudian Anda bisa mendapatkan alamatnya
this
, bahkan tanpa pernah menugaskan functor ke variabel:Ini memiliki keuntungan bahwa ini 100% portabel, dan sangat mudah untuk dipikirkan dan dipahami.
sumber
struct { void operator()() { std::cout << "Address of this functor is => " << this << '\n'; } } f;
Tangkap lambda:
sumber
std::function
tidak diperlukan di sini, dan itu datang dengan biaya yang cukup besar. Juga, menyalin / memindahkan objek itu akan merusaknya.Itu mungkin tetapi sangat tergantung pada platform dan optimisasi kompiler.
Pada sebagian besar arsitektur yang saya tahu, ada register yang disebut pointer instruksi. Inti dari solusi ini adalah untuk mengekstraknya ketika kita berada di dalam fungsi.
Pada amd64, kode berikut harus memberi Anda alamat yang dekat dengan fungsi.
Tetapi misalnya pada gcc https://godbolt.org/z/dQXmHm dengan
-O3
fungsi level optimasi mungkin diuraikan.sumber
thread_local
durasi penyimpanan otomatis atau . Apa yang Anda coba dapatkan di sini adalah alamat pengirim fungsi, bukan objek. Tetapi bahkan itu tidak akan berfungsi karena prolog fungsi yang dihasilkan kompiler mendorong ke stack dan menyesuaikan pointer stack untuk membuat ruang untuk variabel lokal.