当绑定对象过期时,std::bind 创建的仿函数的行为是否定义明确?
Is the behavior of a functor created by std::bind well-defined when the bound object expires?
以下代码的行为是否定义明确? f()
调用的行为如何?
#include <functional>
#include <iostream>
struct A
{
void shout()
{
std::cout <<"shout";
}
};
int main()
{
std::function<void()> f;
{
A a;
f = std::bind(&A::shout, &a);
}
f(); // what happens here?
}
您的代码最终在函数包装器中存储了一个悬空引用(对不再存在的对象),并且调用该函数会导致未定义的行为。
如果原始对象的寿命不如包装器那么长,您始终可以在包装器中存储对象的副本:
f = std::bind(&A::shout, a);
// ^^^ copy
为了表明这是未定义的,请注意存储的地址变为无效指针值 - [basic.stc]/3:
When the end of the duration of a region of storage is reached, the
values of all pointers representing the address of any part of the
deallocated storage become invalid pointer values ([basic.compound]).
在对绑定仿函数的调用中,取消引用该指针以执行成员函数调用,其中 [basic.stc.dynamic.deallocation]/4 适用:
Indirection through an invalid pointer value and passing an invalid
pointer value to a deallocation function have undefined behavior.
相反,您可以为每个值绑定 a
(省略与号)。
以下代码的行为是否定义明确? f()
调用的行为如何?
#include <functional>
#include <iostream>
struct A
{
void shout()
{
std::cout <<"shout";
}
};
int main()
{
std::function<void()> f;
{
A a;
f = std::bind(&A::shout, &a);
}
f(); // what happens here?
}
您的代码最终在函数包装器中存储了一个悬空引用(对不再存在的对象),并且调用该函数会导致未定义的行为。
如果原始对象的寿命不如包装器那么长,您始终可以在包装器中存储对象的副本:
f = std::bind(&A::shout, a);
// ^^^ copy
为了表明这是未定义的,请注意存储的地址变为无效指针值 - [basic.stc]/3:
When the end of the duration of a region of storage is reached, the values of all pointers representing the address of any part of the deallocated storage become invalid pointer values ([basic.compound]).
在对绑定仿函数的调用中,取消引用该指针以执行成员函数调用,其中 [basic.stc.dynamic.deallocation]/4 适用:
Indirection through an invalid pointer value and passing an invalid pointer value to a deallocation function have undefined behavior.
相反,您可以为每个值绑定 a
(省略与号)。