C++ 当绑定对象过期时,std::bind创建的函子的行为是否定义良好?
以下代码的行为是否定义良好?C++ 当绑定对象过期时,std::bind创建的函子的行为是否定义良好?,c++,language-lawyer,stdbind,C++,Language Lawyer,Stdbind,以下代码的行为是否定义良好?f()调用的行为如何 #include <functional> #include <iostream> struct A { void shout() { std::cout <<"shout"; } }; int main() { std::function<void()> f; { A a; f = std::bind(&A::s
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?
}
#包括
#包括
结构A
{
无效呼喊()
{
std::cout您的代码最终在函数包装器中存储了一个悬空引用(指向不再存在的对象),调用函数会导致未定义的行为
如果原始对象的寿命不如包装器长,则始终可以在包装器中存储对象的副本:
f = std::bind(&A::shout, a);
// ^^^ copy
要显示未定义,请注意存储的地址变为无效指针值-:
当到达存储区域的持续时间结束时
所有指针的值,这些指针表示
解除分配的存储将成为无效的指针值([basic.component])
在对绑定函子的调用中,该指针被取消引用以执行成员函数调用,适用于:
通过无效指针值进行间接寻址并传递无效
指向解除分配函数的指针值具有未定义的行为
相反,您可以为每个值绑定a
(省略符号)。此外,对成员函数的调用需要一个对象[class.mfct.non static]p1。请注意,如果shout
是静态的,则代码没有UB AFAIK。(如果发生间接寻址,则存在一个基本问题*/*的时间。)@dyp Edit:哎呀,我以为你提到了/2。p2有DR吗?@dyp发生了间接寻址,这会导致未定义的行为。我们可以像使用空指针一样放松,允许丢弃间接寻址的值,但这不是我们想要的。@dyp/2的缺陷不在于它不一致,而在于它应该ld涵盖了传递无效左值的情况。(与其说是缺陷,不如说是需要澄清。/1对于需要的对象不够明确。)