问题
I would want to use a constexpr value in a lambda. Reading the answer to Using lambda captured constexpr value as an array dimension, I assumed the following should work:
#include<array>
int main()
{
constexpr int i = 0;
auto f = []{
std::array<int, i> a;
};
return 0;
}
However, Clang 3.8 (with std=c++14) complains that
variable 'i' cannot be implicitly captured in a lambda with no capture-default specified
Should this be considered a bug in clang 3.8?
BTW:
The above code does compile with gcc 4.9.2. If I change the lambda expresion to capture explicitly:
...
auto f = [i]{
...
clang 3.8 compiles it, but gcc 4.9.2 fails:
error: the value of ‘i’ is not usable in a constant expression ...
回答1:
Should this be considered a bug in clang 3.8?
Yep. A capture is only needed if [expr.prim.lambda]/12 mandates so:
Note in particular the highlighted example. f(x) does not necessitate x to be captured, because it isn't odr-used (overload resolution selects the overload with the object parameter). The same argumentation applies to your code - [basic.def.odr]/3:
A variable
xwhose name appears as a potentially-evaluated expressionexis odr-used byexunless applying the lvalue-to-rvalue conversion (4.1) toxyields a constant expression (5.20) that does not invoke any non-trivial functions…
This requirement is certainly met.
…and, if
xis an object,exis an element of the set of potential results of an expressione, where either the lvalue-to-rvalue conversion (4.1) is applied toe, oreis a discarded-value expression (Clause 5).
i is its set of potential results as per [basic.def.odr]/(2.1), and the l-t-r conversion is indeed immediately applied as its passed to a non-type template parameter of object type.
Hence, as we have shown that (12.1) isn't applicable - and (12.2) clearly isn't, either - Clang is wrong in rejecting your snippet.
来源:https://stackoverflow.com/questions/33873788/can-i-use-a-constexpr-value-in-a-lambda-without-capturing-it