【问题标题】:Is it legal to assign to std::function that was moved分配给被移动的 std::function 是否合法
【发布时间】:2018-12-18 20:01:43
【问题描述】:

以下代码是否合法:

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 可能会引发未定义的行为。

【问题讨论】:

标签: c++ c++11 stdmove


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

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

    由于该函数是按值复制的,“f”的原始值决不需要解析对新创建函数的调用。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-12-18
      • 1970-01-01
      • 1970-01-01
      • 2012-04-18
      • 2023-04-08
      • 1970-01-01
      • 1970-01-01
      • 2018-03-11
      相关资源
      最近更新 更多