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
Était-ce utile?

La 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;
...

Autres conseils

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.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top