分配给被移动的 std::function 是否合法
Is it legal to assign to std::function that was moved
下面的代码是否合法:
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 可能会调用未定义的行为。
由于您在 lambda 中按值捕获([i, previous_f]
复制了 previous_f
,与您传递的参数完全分离),它将有效。最后,f
将(间接地,在 lambda 的上下文中)保存所有函数的副本。
请注意,您没有使用 std::move
。但是,即使那样,也可以不在意原作previous_f
被破坏的情况下进行复制。
这是否安全取决于函数对象是按值传递还是按引用传递。正如您的代码所示,"CreateFunction" 中的函数按值传递,并且在返回的 lambda 中按值复制。
因为函数是按值复制的,所以根本不需要 'f' 的原始值来解析对新创建函数的调用。
请注意,在 'CreateFunction' 中使用 receive const-reference 可能会更好,因为这样可以最大程度地减少按值复制函数对象的次数。
下面的代码是否合法:
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 可能会调用未定义的行为。
由于您在 lambda 中按值捕获([i, previous_f]
复制了 previous_f
,与您传递的参数完全分离),它将有效。最后,f
将(间接地,在 lambda 的上下文中)保存所有函数的副本。
请注意,您没有使用 std::move
。但是,即使那样,也可以不在意原作previous_f
被破坏的情况下进行复制。
这是否安全取决于函数对象是按值传递还是按引用传递。正如您的代码所示,"CreateFunction" 中的函数按值传递,并且在返回的 lambda 中按值复制。
因为函数是按值复制的,所以根本不需要 'f' 的原始值来解析对新创建函数的调用。
请注意,在 'CreateFunction' 中使用 receive const-reference 可能会更好,因为这样可以最大程度地减少按值复制函数对象的次数。