Ketika "ini" ditangkap oleh lambda, apakah itu harus digunakan secara eksplisit?

27

Contoh-contoh yang saya temukan yang menangkap thisdalam lambda menggunakannya secara eksplisit; misalnya:

capturecomplete = [this](){this->calstage1done();};

Tetapi tampaknya juga memungkinkan untuk menggunakannya secara implisit; misalnya:

capturecomplete = [this](){calstage1done();};

Saya menguji ini di g ++, dan dikompilasi.

Apakah ini standar C ++? (dan jika ya, versi yang mana), atau apakah itu suatu bentuk ekstensi?

plugwash
sumber
1
Jawabannya benar, tetapi ada kemungkinan alasan untuk menggunakan this->secara eksplisit, yaitu untuk memastikan bahwa nilai yang ditangkap secara eksplisit digunakan secara eksplisit. Catatan yang [](){ calstage1done(); }tidak sah, karena thistidak akan ditangkap; tapi ketika menangkap thissecara eksplisit, itu mengejutkan bagi tubuh fungsi untuk tampil sekilas tidak benar-benar menggunakan nilai ditangkap: [this](){ calstage1done(); }.
Kyle Strand
Saya bisa melihat ini, tetapi pada saat yang sama tampak mengerikan untuk apa yang seharusnya menjadi tugas sederhana.
plugwash
1
Saya ingat MSVC (mungkin hanya tahun 2015) juga mengalami masalah dalam menangkap thisdan menggunakannya dalam lambda yang mungkin juga menjadi alasan untuk menggunakannya secara eksplisit
Flamefire
@plugwash: Pengembang cenderung selalu malas dan ingin meminimalkan hal-hal, dan perancang bahasa tidak berbeda. Namun, kata kerja seringkali diperlukan untuk menyelesaikan ambiguitas, dan itulah yang terjadi di sini.
Flater

Jawaban:

25

Ini adalah standar dan telah seperti ini sejak C ++ 11 ketika lambdas ditambahkan. Menurut cppreference.com :

Untuk tujuan pencarian nama, menentukan jenis dan nilai thispointer dan untuk mengakses anggota kelas non-statis, tubuh operator fungsi panggilan tipe penutupan dipertimbangkan dalam konteks ekspresi lambda.

struct X {
    int x, y;
    int operator()(int);
    void f()
    {
        // the context of the following lambda is the member function X::f
        [=]()->int
        {
            return operator()(this->x + y); // X::operator()(this->x + (*this).y)
                                            // this has type X*
        };
    }
};
Ayxan
sumber
19

Ini sepenuhnya standar dan telah sejak lambdas diperkenalkan di C ++ 11.

Anda tidak perlu menulis di this->sana.

Lightness Races di Orbit
sumber