gpt4 book ai didi

c++ - 为什么此代码工作/失败取决于范围关闭创建于?

转载 作者:行者123 更新时间:2023-11-30 03:46:52 25 4
gpt4 key购买 nike

以下代码将回调包装在另一个回调中,但根据内部回调的范围,代码要么运行成功,要么失败。

下面的代码按原样运行正常,但如果回调是在 make_callback() 中完成的,而不是直接在 main 中完成的,则代码会失败:

frame #110339: 0x000000010000453c a.out`std::__1::__function::__func<void stuff<B>(std::__1::function<void (B*)>)::'lambda'(A*), std::__1::allocator<void stuff<B>(std::__1::function<void (B*)>)::'lambda'(A*)>, void (A*)>::operator()(A*&&) + 60

frame #110340: 0x0000000100002fdf a.out`std::__1::function<void (A*)>::operator()(A*) const + 159

代码:

#include <functional>
#include <list>

class A {
public:
virtual ~A(){}
};

class B : public A {
public:
virtual ~B(){}
};


std::list<std::function<void(A*)>> callbacks;
void stuff(std::function<void(A*)> callback){
callbacks.push_back(callback);
printf("Now have %d callbacks\n", (int)callbacks.size());

}

template<typename T>
void stuff(std::function<void(T*)> callback) {


stuff([&](A* a) {
T * b = dynamic_cast<T*>(a);
if (b!= nullptr) {
printf("Calling actual callback\n");
callback(b);
} else {
printf("Not calling actual callback\n");
}
}
);
}

void make_callback()
{
stuff<B>([&](B*b){printf("Hello with a B\n");});
}

int main()
{
//make_callback();
stuff<B>([&](B*b){printf("Hello with a B\n");});

A a;
B b;
for (auto callback : callbacks) {
callback(&a);
callback(&b);
}
}

最佳答案

由于 stuff 模板中的引用捕获,当函数被调用时,callback 是悬空引用。 (指向参数,参数的生命周期已经结束。)
与往常一样,使用悬空引用是未定义的,可能看起来有效,也可能无效。

此代码中不需要引用捕获。

关于c++ - 为什么此代码工作/失败取决于范围关闭创建于?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33932622/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com