constexpr değişkeni yakalanmadı

Dec 10 2020

Aşağıdaki kod clang'da derlenmez (GCC'de yapar):

struct A{
    int a;
};

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

Clang'ın hatası, değişken 'x', varsayılan yakalama belirtilmemiş bir lambda'da örtük olarak yakalanamaz , ancak constexpr değişkenlerinin her zaman yakalandığını düşündüm.

X bir int ise, kod şunları derler:

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

İlginç bir şekilde, aşağıdaki kod da derler:

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

Clang doğru mu? Eğer öyleyse, gerekçe nedir? -Std = c ++ 17 kullanıyorum

--DÜZENLE--

Şu soru: Bir lambda'da onu yakalamadan bir constexpr değeri kullanabilir miyim? bununla ilgili değil, clang11'de olduğu gibi artık bir sorun değil: aslında, yukarıda belirtildiği gibi, eğer x bir int ise, clang11 derler.

Örnek kod da mevcut https://godbolt.org/z/rxcYjz

Yanıtlar

2 DavisHerring Dec 25 2020 at 07:09

Ne zaman return x;ilk örnekte, başvuracağımız Abir bağlayıcı içerir 'ın kopya kurucu, başvuru için xve böylece ODR-kullanımları o. Sabit ifadelerde kullanılabilen bir değerin önemsiz bir kopyasının daha fazla bir odr kullanımı oluşturmaması gerektiği argümanı yapılabilir return x.a;, ancak bu kuralda böyle bir istisna yoktur, bu nedenle Clang bunu reddetmek için doğrudur .

Pratik bir konu olarak, onu yakalama ihtiyacından kaçınmak için elbette herhangi bir constexprdeğişken yapabilirsiniz static.