如何将新的lambda表达式赋给函数对象?

时间:2018-01-22 14:33:51

标签: c++ c++11 lambda const

已定义lambda表达式并将其分配/绑定到函数对象。现在我想为该函数对象分配一个新函数。但是在某些情况下,这个赋值会编译错误。

我了解错误来自auto关键字自动将const添加到函数对象。无论如何使用auto和其他关键词来删除const绑定?我并不认为mutable可以像我的代码那样达到目的。

This帖子解释了为什么没有解决方案。 This帖子提出了一个使用结构的解决方案,但我想知道是否有更多优雅的方法来实现它。

#include <functional>
#include <memory>
#include <queue>
#include <random>
#include <utility>

using namespace std;

void f1();

int main() {
  srand(0);
  f1(); 
  return 0;
}

void f1() {
  using my_pair = pair<int,int>;
  int ref = 2;
  function<bool(const my_pair &,const my_pair &)> comp_1 = [&ref](const my_pair &LHS, const my_pair &RHS) {return LHS.first-ref > RHS.first-ref;};
  comp_1 = [&ref](const my_pair &LHS, const my_pair &RHS) {return LHS.first < RHS.first;};
  // So far so good.
  auto comp_2 = [&ref](const my_pair &LHS, const my_pair &RHS) mutable {return LHS.first-ref > RHS.first-ref;};
    // Compile error below!
  comp_2 = [&ref](const my_pair &LHS, const my_pair &RHS) mutable {return LHS.first < RHS.first;};
    // Compile error above

    // Applications of the function object
  priority_queue<my_pair, vector<my_pair>, decltype(comp_2)> myHeap(comp_2);
  for (int i=0; i<10; i++) myHeap.emplace(rand()%10,rand()%20);
  while (!myHeap.empty()) {
    printf("<%d,%d>\n",myHeap.top().first,myHeap.top().second);
    myHeap.pop();
  }

}

1 个答案:

答案 0 :(得分:2)

每个lambda表达式都是匿名类型的文字;两个不同的lambda,即使是相同的原型和相同的捕获列表,也是两种不同类型的对象。而且,this type's assignment operator is deleted,所以你甚至不可能将它分配给自己:

$ cat omg.cpp
int main() {
    auto f = []{};
    f = f;
}
$ g++ omg.cpp
omg.cpp: In function ‘int main()’:
omg.cpp:3:4: error: use of deleted function ‘main()::<lambda()>& main()::<lambda()>::operator=(const main()::<lambda()>&)’
  f = f;
    ^
omg.cpp:2:12: note: a lambda closure type has a deleted copy assignment operator