It's not possible as auto
variables need an initialization expression to deduce the type from, but you can declare update to be a std::function
:
std::function<void()> update;
...
Question
I want to do something like this (define a lambda function based on some condition):
auto update;
if(condition)
{
update = [this]() {this->someField += 1;};
}
else
{
update = [this]() {this->someField -= 1;};
}
update();
Is it actually possible by the one way or another? An error from gcc-4.8 for this code is
error: declaration of ‘auto update’ has no initializer
Solution
It's not possible as auto
variables need an initialization expression to deduce the type from, but you can declare update to be a std::function
:
std::function<void()> update;
...
OTHER TIPS
Store a reference to data you change:
int value;
auto update [this,&value]() {this->someField += value;}
if(condition) {
value = 1;
} else {
value = -1;
}
update();
If you want the lambda to outlive the current scope, store a copy of a smart pointer:
auto value=std::make_shared<int>();
auto update [this,value]() {this->someField += *value;}
if(condition) {
*value = 1;
} else {
*value = -1;
}
update();
finally, you can type-erase the lambda and store it in a std::function<void()>
, but the invocation overhead of a std::function<void()>
can make this a bad idea in some contexts.
There is also the somewhat upside down method:
auto meta_update = [this,value](int x) {return [this,x](){this->someField += x;};};
auto update = condition?meta_update(1):meta_update(-1);
update();
where we store a lambda lambda and delambinate one stage to produce func()
.
If the if
body is complex, you can do this:
auto value=std::make_shared<int>();
auto meta_update = [this,value](int x) {return [this,x](){this->someField += x;};};
auto update = [&]()->decltype(meta_update(0)) {
if(condition) {
// lots of code
return meta_update(1);
} else {
// even more code
return meta_update(-1);
}
}();
update();
and in C++1y you can omit the ()->decltype(meta_update(0))
portion.