Open mmatrosov opened 5 months ago
@llvm/issue-subscribers-clang-frontend
Author: Mikhail Matrosov (mmatrosov)
... and is non-const
It is a const reference, see https://en.cppreference.com/w/cpp/types/is_const#Notes:
Notes If
T
is a reference type thenis_const<T>::value
is always false. The proper way to check a potentially-reference type for const-ness is to remove the reference:is_const<typename remove_reference<T>::type>
.
https://godbolt.org/z/j1Y548xY5
Edit: Use std::remove_reference_t
As if they were applied to the outer
ir
in the body of the function.
Yes, that should be the expected behaviour. Since ir
in decltype(ir)
is an unevaluated context, it refers to the local entity declared in main
, not the member of the lambda object. This matches the example given here: https://eel.is/c++draft/expr.prim.id.unqual#example-1
https://eel.is/c++draft/expr.prim.id.unqual#3.sentence-3
If naming the entity from outside of an unevaluated operand within S would refer to an entity captured by copy in some intervening lambda-expression, then let E be the innermost such lambda-expression.
(Bold mine, the transformation shouldn't happen)
Thanks a lot for the links! It is pretty hard for me to get from the text why decltype
should behave this way, but it is clear from the example you've referenced that this is indeed the correct behavior. Even though it looks quite surprizing to me. Do I understand correctly that when I write evaluated ir
in the lambda body (e.g. assign to it) it refers to the implicit data member of the closure, while when I write unevaluated ir
(e.g. apply decltype
on it) it refers to the original object outside of the lambda?
Consider the following program (https://godbolt.org/z/8EY4G3n68):
Here
ir
is a const ref captured by value. It is represented byconst int
member in the closure object (https://eel.is/c++draft/expr.prim.lambda.capture#10):(I personally see no reason why
const
qualifier should not be stripped off during capture, but this is another story)The line
ir = 13
does not compile with the errorcannot assign to a variable captured by copy in a non-mutable lambda
which clearly tells that the type is notint
(and the error is a bit misleading, since the lambda is markedmutable
). The return code of the program is zero, which tells that the type is not a reference.However, both
static_asserts
compile, sayingir
within the closure is a reference, and is non-const. As if they were applied to the outerir
in the body of the function.