声明后定义lambda函数?

时间:2014-05-13 15:03:51

标签: c++11 lambda

我想做这样的事情(根据某些条件定义一个lambda函数):

auto update;
if(condition)
{
    update = [this]() {this->someField += 1;};
}
else
{
    update = [this]() {this->someField -= 1;};
}

update();

这种方式真的可能吗? gcc-4.8对此代码的错误是

error: declaration of ‘auto update’ has no initializer

2 个答案:

答案 0 :(得分:5)

由于auto变量需要初始化表达式来推断类型,因此不可能,但您可以将更新声明为std::function

std::function<void()> update;
...

答案 1 :(得分:3)

存储对您更改的数据的引用:

int value;
auto update [this,&value]() {this->someField += value;}
if(condition) {
  value = 1;
} else {
  value = -1;
}

update();

如果您希望lambda比当前范围更长,请存储智能指针的副本:

auto value=std::make_shared<int>();
auto update [this,value]() {this->someField += *value;}
if(condition) {
  *value = 1;
} else {
  *value = -1;
}

update();

最后,您可以键入 - 擦除lambda并将其存储在std::function<void()>中,但std::function<void()>的调用开销可能会在某些情况下使其成为一个坏主意。

还有一种颠倒的方法:

auto meta_update = [this,value](int x) {return [this,x](){this->someField += x;};};
auto update = condition?meta_update(1):meta_update(-1);
update();

我们存储一个lambda lambda并将一个阶段放弃以产生func()

如果if正文很复杂,你可以这样做:

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();

在C ++ 1y中你可以省略()->decltype(meta_update(0))部分。