Доступ к переменной constexpr внутри лямбда-выражения без захвата

В следующем примере я могу получить доступ к переменной constexpr x из лямбда y без явного ее захвата. Это невозможно, если x не объявлен как constexpr.

Существуют ли специальные правила, применимые к constexpr для захвата?

int foo(auto l) {
    // OK
    constexpr auto x = l();
    auto y = []{return x;};
    return y();

    // NOK
    // auto x2 = l();
    // auto y2 = []{ return x2; };
    // return y2();        
}

auto l2 = []{return 3;};

int main() {
    foo(l2);
}

Ответ 1

Существуют ли специальные правила, применимые к constexpr для захвата/доступа?

Да, переменные constexpr могут быть прочитаны без захвата в лямбда:

Выражение лямбда может считывать значение переменной без ее захвата, если переменная

  • имеет константный интегральный или перечисляемый тип const и был инициализирован с постоянным выражением или
  • является constexpr и тривиально копируется.