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
有帮助吗?

解决方案

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

其他提示

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.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top