包含lambda的类型被分配后会发生什么?

Jar*_*ock 10 c++ lambda

假设我有某种类型包装函数,也许是lambda函数:

template<typename Function>
  struct my_struct
{
  Function f;

  my_struct(const Function &f) : f(f) {}
};
Run Code Online (Sandbox Code Playgroud)

分配此类型的实例时会发生什么?我的理解是lambdas是不可变的,并删除了赋值运算符.

然而,当我在下面的代码片段中分配这种类型的对象时,不会发出错误:

// a structure which contains a function;
// possibly a lambda function
template<typename Function>
  struct my_struct
{
  Function f;

  my_struct(const Function &f) : f(f) {}

  // XXX adding this assignment operator causes an error
  //my_struct &operator=(const my_struct &other)
  //{
  //  f = other.f;
  //  return *this;
  //}
};

template<typename Function>
my_struct<Function> make_struct(const Function &f)
{
  return my_struct<Function>(f);
}

int main()
{
  // create some lambda
  auto lambda = [](int x){return x;};

  // make a struct containing a copy of the lambda
  auto x = make_struct(lambda);

  // try to assign to the struct, which
  // presumably assigns to the enclosed lambda
  x = make_struct(lambda);

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

添加注释掉的赋值运算符会产生错误,如预期的那样:

$ g++-4.6 -std=c++0x test.cpp
test.cpp: In member function ‘my_struct<Function>& my_struct<Function>::operator=(const my_struct<Function>&) [with Function = main()::<lambda(int)>, my_struct<Function> = my_struct<main()::<lambda(int)> >]’:
test.cpp:34:25:   instantiated from here
test.cpp:13:5: error: use of deleted function ‘main()::<lambda(int)>& main()::<lambda(int)>::operator=(const main()::<lambda(int)>&)’
test.cpp:27:18: error: a lambda closure type has a deleted copy assignment operator
Run Code Online (Sandbox Code Playgroud)

那么,是否可以使用lambda成员变量创建可赋值类型?这似乎是一个想要尝试的合理的事情.boost::transform_iterator例如,考虑将lambda与.

GMa*_*ckG 13

你很亲密 lambda具有隐式复制构造函数,并且可能具有 - 取决于捕获的值 - 隐式移动构造函数.它有一个删除的复制赋值运算符.

换句话说,您可以构建它,但您可能不会分配它.如果您正在寻找通用函数对象,则需要使用std::function<>.它将函数模拟为一等值.


请注意,immutable与assignable不同.当lambda被称为mutable时,这意味着它的函数调用体可以修改lambda的成员(即函数不是const):

int i = 0;

auto okay = [=](int x) mutable { i += x; };
auto error = [=](int x) { i += x; };
Run Code Online (Sandbox Code Playgroud)

这些中的每一个都是可复制的且不可分配的.

  • 感谢您的解释.删除分配太糟糕了 - 它似乎使lambda与```boost :: transform_iterator```不兼容,至少在当前的实现方面是这样. (4认同)