Reputation: 421
int main() {
int x;
auto& getx = [&]() {
return x;
}
getx() = 1;
}
This doesn't seem possible, as it gives me:
error: cannot bind non-const lvalue reference of type 'main()::<lambda()>&' to an rvalue of type 'main()::<lambda()>'|
Why ? and how to do it
Upvotes: 1
Views: 523
Reputation: 180500
A lambda expression creates a temporary object (called a closure) of an unknown class type. Temporary objects can't be assigned to non-const references. That means you need
auto&& getx = [&]() {
return x;
}
so that you get an rvalue reference to the closure, or
auto getx = [&]() {
return x;
}
so you just get the closure.
That will get the code to compile, but still needs one more bit to make getx
's return value to be a reference to x
. To do that you need to add
auto getx = [&]() -> int& {
return x;
}
// or
auto getx = [&]() -> auto& {
return x;
}
// or
auto getx = [&]() -> decltype(auto) {
return x;
};
Also note that main
must always return an int
. You should turn up your compiler warning level so that it errors out if you try and use void main
.
Upvotes: 3
Reputation: 20918
You have to specify that lambda returns reference to int - int&
, and call closure by ()
:
auto& getx = [&]() -> int& { // -> int& added
return x;
}(); // () added
Temporary value cannot be bound to lvalue reference. If you want to make getx
to be as a reference to x
variable, you have to return reference from your lambda.
Upvotes: 2