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
Was it helpful?

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top