variabel constexpr tidak ditangkap

Dec 10 2020

Kode berikut tidak dapat dikompilasi di clang (seperti di GCC):

struct A{
    int a;
};

auto test(){
    constexpr A x{10};
    return []{
        return x; // <-- here x is A: clang doesn't compile
    }();
}

Kesalahan Clang adalah variabel 'x' tidak dapat ditangkap secara implisit dalam lambda tanpa capture-default yang ditentukan , tapi saya pikir variabel constexpr selalu ditangkap.

Jika x adalah int, kode mengkompilasi:

auto test(){
    constexpr int x{10};
    return []{
        return x; // <-- here x is int: clang is ok
    }();
}

Menariknya, kode berikut juga dikompilasi:

auto test(){
    constexpr A x{10};
    return []{
        return x.a;
    }();
}

Apakah dentang benar? Jika ya, apa alasannya? Saya menggunakan -std = c ++ 17

--EDIT--

Pertanyaan berikut: Dapatkah saya menggunakan nilai constexpr di lambda tanpa menangkapnya? tidak terkait dengan yang satu ini, karena dengan clang11 itu tidak lagi menjadi masalah: sebenarnya, seperti yang dinyatakan di atas, jika x adalah kompilasi int, clang11.

Kode sampel juga ada di https://godbolt.org/z/rxcYjz

Jawaban

2 DavisHerring Dec 25 2020 at 07:09

Ketika Anda return x;dalam contoh pertama, Anda harus memanggil Akonstruktor salinan, yang melibatkan pengikatan referensi ke xdan karenanya odr-menggunakannya. Argumen dapat dibuat bahwa salinan sepele dari nilai yang dapat digunakan dalam ekspresi konstan tidak boleh menggunakan odr-use lebih dari return x.a;, tetapi tidak ada pengecualian seperti itu dalam aturan itu, jadi Clang benar untuk menolaknya.

Secara praktis, tentu saja Anda dapat membuat constexprvariabel apa pun staticuntuk menghindari kebutuhan untuk menangkapnya.