以下代码是否合法:
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可能会引起未定义的行为。
答案 0 :(得分:1)
由于您是通过lambda中的值捕获的([i, previous_f]
会复制previous_f
的副本,并且完全与您传递的参数分离),因此该副本将有效。最后,f
将(在lambda的上下文中间接)保存所有函数的副本。
请注意,您没有使用std::move
。但是,即使在那种情况下,您也可以复制副本而不必关心原始previous_f
是否已被破坏。
答案 1 :(得分:1)
这是否安全取决于函数对象是通过值传递还是通过引用传递。如您的代码所示,“ CreateFunction”中的函数按值传递,此外,还按值复制到返回的lambda中。
因为该函数已按值复制,所以解析新创建函数的调用无需使用原始值“ f”。
请注意,最好在'CreateFunction'中使用const引用,因为这样可以最大程度地减少按值复制功能对象的次数。