On cppreference I read the following
A lambda expression can use a variable without capturing it if the variable
- is a non-local variable or has static or thread local storage duration (in which case the variable cannot be captured), or
- is a reference that has been initialized with a constant expression.
A lambda expression can read the value of a variable without capturing it if the variable
- has const non-volatile integral or enumeration type and has been initialized with a constant expression, or
- is constexpr and has no mutable members.
As regards the first bullet, I think this is a relevant example
int x = 17; // non-local variable
static int y = 17; // variable wht static storage duration (am I correct?)
int main () {
auto g = [x, y] // error for both, emptying the capture fixes the error
{ (void)(x + y); };
}
As regards the third bullet, I think this is an example for it (int can be changed to an enum, I understand)
struct C{};
int main () {
int nc{}; // non const => need capture
constexpr int ce{3};
int const cce{ce}; // const init-ed with constexpr => not need to capture
int const cn{nc}; // const init-ed with non-constexpr => need capture
int const volatile cv{}; // const but volatile => need capture
C const c{};
auto lam = [c, nc, cn, cv]{
(void)(nc + cce + cn + cv);
(void)c;
};
lam();
}
However, as regards the second bullet, I don't really understand what a reference that has been initialized with a constant expression is. I don't think it is something like this:
constexpr int x{3};
int const&/* this is a reference */ y = x/* this is a constant expression */;
Also the fourth is unclear to me. I thought the following would be erroneous because of that point, but it is just fine:
constexpr struct M {
mutable int x;
} m{3};
int main () {
auto lam = []{
(void)m;
};
lam();
}
I'd really like if the answer would explain the matter with reference to the standard.