On 2013-01-18 02:20, Andy Venikov wrote:
> I was always under impression that lambdas could have cv-qualifiers.
No, the grammar doesn't support them to be added. The relevant part is:
lambda-declarator:
( parameter-declaration-clause ) mutable_opt
exception-specification_opt attribute-specifier-seq_opt
trailing-return-type_opt
Note that const qualifiers aren't possible, because the effective
function call operator has an const-qualifier unless you add the
"mutable" keyword as shown above because 5.1.2 p5 says:
"[..] This function call operator is declared const (9.3.1) if and only
if the lambda-expression’s parameter-declaration-clause is not followed
by mutable. It is neither virtual nor declared volatile. [..]"
Side note: The effect of the current rules is that you cannot add
volatile qualifiers to the lambda function call operator at all (neither
implicit nor explicit).
> At least that's how I interpreted 5.1.2[5]:
>
> "An attribute-specifier-seq in a lambda-declarator appertains to the
> type of the corresponding function call operator."
This interpretation is wrong, because cv-qualifiers are not part of
attribute-specifier-seq. The latter exist to add attributes, but
cv-qualifiers aren't attributes, they are a completely separate grammar
element.
> For example:
>
> ....
> SomeExpensiveToCopyClass a;
> ...
> [&]() const { //use const a here }
You don't need this, because const is implied.
> This way the compiler will notify me if I'm trying to modify a in a
> lambda function.
No, it wouldn't, even if it were allowed. Remember that capturing by
reference is intended to bind a reference or pointer to the
corresponding variable. 5.1.2 p17 says:
"Every id-expression that is an odr-use (3.2) of an entity captured by
copy is transformed into an access to the corresponding unnamed data
member of the closure type."
For reference capturing there does not exist a transformation into a
corresponding data member of the closure. Typically implementations will
use a pointer or reference to that entity, but this has the effect that
cv-qualifiers are considered "flat" here, similar to
struct Lambda {
SomeExpensiveToCopyClass* a;
void operator()() const { ... } // Modifying *a is OK
};
> Unfortunately, when compiled under gcc (4.7.2), it gives me an error
> that const does not belong there.
The compiler is correct, because cv-qualifiers aren't feasible in this
context.
> Is my understanding not correct?
No.
> Or is it just a gcc bug (i.e.
> not-implemented feature)?
No.
HTH & Greetings from Bremen,
Daniel Krügler