0

以下代码是否合法:

std::function<void()> CreateFunction(int i, std::function<void()> previous_f) {
   return [i,previous_f] { 
     std::cout << i << std::endl;
     previous_f();
   };
}


int main()
{
  std::function<void()> f = []{};
  for(int i=0;i<3;++i) {
    f = CreateFunction(i, f);
  }
  f();
}

它按预期编译和运行 - http://cpp.sh/2smb3,但我担心在 f 移动后分配给 f 可能会调用未定义的行为。

4

2 回答 2

1

由于您在 lambda 中按值捕获([i, previous_f]复制previous_f,与您传递的参数完全分离),因此它将是有效的。最后,f将(间接地,在 lambda 的上下文中)保存所有函数的副本。

请注意,您没有使用std::move. 但是,即使在这种情况下,当您制作不关心原件previous_f已被破坏的副本时,它仍然可以。

于 2018-12-18T20:06:23.463 回答
1

这是否安全取决于函数对象是通过值传递还是通过引用传递。正如您的代码所示,“CreateFunction”中的函数按值传递,此外,在返回的 lambda 中按值复制。

因为该函数已按值复制,所以“f”的原始值决不需要解析对新创建函数的调用。

需要注意的是,最好在“CreateFunction”中使用接收常量引用,因为这样可以最大限度地减少函数对象按值复制的次数。

于 2018-12-18T20:14:07.023 回答