auto foo = "You're using g++!";
auto compiler_detector = [foo](auto foo) { std::puts(foo); };
compiler_detector("You're using clang++!");
clang ++ 3.6.0 dan yang lebih baru mencetak "Anda menggunakan clang ++!" dan peringatkan tentang tangkapan
foo
yang tidak digunakan.g ++ 4.9.0 dan yang lebih baru mencetak "Anda menggunakan g ++!" dan peringatkan tentang parameter
foo
yang tidak digunakan.
Kompiler apa yang lebih akurat mengikuti Standar C ++ di sini?
struct Lambda { template<typename T> void operator()(T foo) const { /* ... */ } private: decltype(outer_foo) foo{outer_foo}; }
.Jawaban:
Pembaruan: seperti yang dijanjikan oleh kursi Inti di kutipan bawah, kodenya sekarang salah bentuk :
Ada beberapa masalah tentang pencarian nama di lambda beberapa waktu lalu. Mereka diselesaikan oleh N2927 :
Pencarian selalu dilakukan dalam konteks ekspresi lambda , tidak pernah "setelah" transformasi ke badan fungsi anggota tipe closure. Lihat [expr.prim.lambda] / 8 :
(Contoh ini juga memperjelas bahwa pencarian entah bagaimana tidak mempertimbangkan anggota penangkapan yang dihasilkan dari tipe penutupan.)
Nama
foo
tidak (kembali) dideklarasikan dalam penangkapan; itu dideklarasikan di blok yang menyertakan ekspresi lambda. Parameterfoo
dideklarasikan dalam blok yang bertumpuk di blok luar itu (lihat [basic.scope.block] / 2 , yang juga secara eksplisit menyebutkan parameter lambda). Urutan pencarian jelas dari blok dalam ke blok luar . Karenanya parameter harus dipilih, yaitu, Clang benar.Jika Anda adalah untuk membuat penangkapan init-capture, yaitu
foo = ""
bukanfoo
, jawabannya tidak akan jelas. Ini karena penangkapan sekarang benar-benar memicu deklarasi yang "blok" tidak diberikan. Saya mengirim pesan ke kursi inti tentang ini, yang menjawabsumber
Saya mencoba mengemas beberapa komentar untuk pertanyaan untuk memberi Anda jawaban yang berarti.
Pertama-tama, perhatikan bahwa:
foo
Oleh karena itu, logikanya akan membuat saya mengatakan pada pandangan pertama bahwa parameter harus membayangi variabel yang ditangkap seolah-olah dalam:
Bagaimanapun, @nm mencatat dengan benar bahwa anggota data non-statis yang dideklarasikan untuk variabel yang diambil salinan sebenarnya tidak bernama. Dengan demikian, anggota data yang tidak disebutkan namanya masih dapat diakses melalui pengidentifikasi (yaitu
foo
). Oleh karena itu, nama parameter dari operator panggilan fungsi masih harus (biarkan saya katakan) bayangan pengenal itu .Seperti yang ditunjukkan dengan benar oleh @nm di komentar untuk pertanyaan:
Karena itu, menurut saya dentang itu benar.
sumber