分配给已移动的std :: function是否合法

时间:2018-12-18 20:01:43

标签: c++ c++11 stdmove

以下代码是否合法:

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

2 个答案:

答案 0 :(得分:1)

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

请注意,您没有使用std::move。但是,即使在那种情况下,您也可以复制副本而不必关心原始previous_f是否已被破坏。

答案 1 :(得分:1)

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

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

请注意,最好在'CreateFunction'中使用const引用,因为这样可以最大程度地减少按值复制功能对象的次数。