The following code
void CMainWindow::someMethod(const CLocationsCollection& parentItem)
{
auto f = [this, parentItem.displayName](){};
}
gives me an error:
error C2143: syntax error : missing ']' before '.'
If I wanted to catch parentItem.displayName
by ref, I'd make a non-dependent alias identifier for it:
const QString& name = parentItem.displayName;
auto f = [this, &name](){}; // Or should it be [this, name] ?
But I need to capture it by value, and I don't want to capture the whole parentItem
because it's heavy. Any solution?
P. S. Names in the capture list must be identifiers. Isn't parentItem.displayName
(as a whole) an identifier? Why can't it be parsed properly by the compiler?
To capture the member variables inside lambda function, capture the “this” pointer by value i.e. std::for_each(vec. begin(), vec. end(), [this](int element){ //.... }
The mutable keyword is used so that the body of the lambda expression can modify its copies of the external variables x and y , which the lambda expression captures by value. Because the lambda expression captures the original variables x and y by value, their values remain 1 after the lambda executes.
The capture list defines what from the outside of the lambda should be available inside the function body and how. It can be either: a value: [x] a reference [&x] any variable currently in scope by reference [&]
Captures default to const value. By default, variables are captured by const value . This means when the lambda is created, the lambda captures a constant copy of the outer scope variable, which means that the lambda is not allowed to modify them.
Note: All standard references in this post are taken from the C++ Standard Draft n3337.
The standard states that a capture must be &
, =
, this
, an identifier, or an identifier preceeded by &
.
5.1.2
Lambda expressions[expr.prim.lambda]
capture-list: capture ..._opt capture-list , capture ..._opt capture: identifier & identifier this
Since parentItem.displayName
is not an identifier, but a "class member access expression". the compiler is correct when rejecting your snippet.
5.2.5p1
Class member access[expr.ref]
A postfix expression followed by a dot
.
or an arrow->
, optionally follow by the keywordtemplate
(14.2), and then followed by an id-expression, is a postfix expression. The postfix expression before the dot or arrow is evaluated;66 the result of that evaluation, together with the id-expression, determines the result of the entire postfix expression.
In C++14 you will be able to use an init-capture to circumvent the issue at hand, looking as the snippet below. It will create a capture with the name display_name, initialized with the value of parentItem.displayName.
[display_name = parentItem.displayName](){ ... };
Sadly such a feature is not available in C++11. The solution to the problem is therefore to make a local reference to the the data-member, and then capture that reference when creating the lambda.
auto& lmb_display_name = parentItem.displayName;
[lmb_display_name](){ ... }; // the lambda will have a copy of `parentItem.displayName`
Note: Your original post seems to imply that the name of a reference R in a lambda's capture-list would make the lambda contain a reference to that which R refers to, something which isn't true, as can be seen by this snippet.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With