Rumah >pembangunan bahagian belakang >C++ >Bolehkah C 11 Lambdas Menangkap Rujukan Tanpa Menggunakan Gelagat Tidak Ditakrifkan?

Bolehkah C 11 Lambdas Menangkap Rujukan Tanpa Menggunakan Gelagat Tidak Ditakrifkan?

Susan Sarandon
Susan Sarandonasal
2024-11-04 22:03:02681semak imbas

Can C  11 Lambdas Capture References Without Invoking Undefined Behavior?

Menangkap Rujukan dalam C 11 Lambdas

Dalam C , ungkapan lambda boleh menangkap pembolehubah daripada skop lampirannya. Walau bagaimanapun, kaedah tangkapan menentukan sama ada pembolehubah diakses melalui rujukan atau nilai. Pertimbangkan kod berikut:

<code class="cpp">#include <functional>
#include <iostream>

std::function<void()> make_function(int& x) {
    return [&]{ std::cout << x << std::endl; };
}

int main() {
    int i = 3;
    auto f = make_function(i);
    i = 5;
    f();
}</code>

Kod ini menangkap pembolehubah x dengan rujukan menggunakan sintaks [&]. Timbul persoalan sama ada program ini menjamin untuk mengeluarkan 5 tanpa menggunakan gelagat yang tidak ditentukan.

Jawapan: Ya

Kod ini dijamin berfungsi dengan betul. Sebelum meneliti perkataan standard yang mendasari, adalah penting untuk ambil perhatian bahawa kod ini berfungsi seperti yang dimaksudkan oleh jawatankuasa C. Walau bagaimanapun, perkataan awal piawaian C 11 tidak jelas mengenai perkara ini, menyebabkan isu CWG 2011 dibangkitkan untuk memberikan penjelasan. Isu ini sedang ditangani dalam pembangunan berterusan standard C.

Penjelasan Standard

Menurut [expr.prim.lambda]/17 standard C, hanya ungkapan id yang merujuk kepada entiti yang ditangkap melalui salinan diubah menjadi akses ahli pada jenis penutupan lambda. ungkapan-id yang merujuk kepada entiti yang ditangkap melalui rujukan dibiarkan sahaja dan terus menandakan entiti yang sama yang akan dilambangkan dalam skop yang disertakan.

Dalam kod di atas, entiti yang ditangkap ialah parameter x fungsi make_function , yang termasuk dalam skop capaian lambda. Oleh itu, rujukan x dalam ungkapan lambda merujuk kepada pembolehubah asal yang diisytiharkan dalam fungsi utama.

Pada mulanya mungkin kelihatan bermasalah bahawa x dirujuk di luar jangka hayatnya selepas fungsi make_function kembali. Walau bagaimanapun, terdapat senario terhad di mana rujukan boleh dirujuk di luar jangka hayatnya. Secara amnya, rujukan sama ada diisytiharkan dalam skop atau merupakan ahli kelas, dalam hal ini kelas itu sendiri mesti berada dalam tempoh hayatnya.

Oleh itu, piawaian itu tidak secara eksplisit melarang penggunaan rujukan di luar jangka hayatnya. Celah ini membenarkan penangkapan rujukan melalui rujukan dalam ungkapan lambda untuk disokong.

Isu CWG 2012 dan Penjelasan Masa Depan

Isu CWG 2012 telah dibangkitkan untuk menangani pengawasan bahawa rujukan boleh dirujuk di luar jangka hayat mereka dalam keadaan tertentu. Penyelesaian isu ini secara tidak sengaja menjejaskan spesifikasi untuk tangkapan lambda melalui rujukan rujukan. Walau bagaimanapun, regresi ini dijangka akan diperbaiki sebelum keluaran C 17.

Atas ialah kandungan terperinci Bolehkah C 11 Lambdas Menangkap Rujukan Tanpa Menggunakan Gelagat Tidak Ditakrifkan?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn