以下代码在另一个回调中包装了一个回调函数,但是根据内部回调的范围,代码要么成功还是失败了。
下面的代码按原样运行正常,但如果回调是在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);
}
}
代码:
$con
答案 0 :(得分:2)
由于您在stuff
模板中进行了引用捕获,callback
是调用该函数时的悬空引用。 (它指的是参数,参数的生命周期已经结束。)
与往常一样,使用悬挂引用是未定义的,可能会或可能不会起作用。
此代码中无需参考捕获。