下面是重现该问题的最少代码:
std::vector<std::function<bool()>> injections;
struct Obj {
void load() {
injections.push_back([&] {
std::cout << ++counter << std::endl;
injections.push_back([&] {
std::cout << ++counter << std::endl;
return true;
});
// std::cout << ++counter << std::endl;
return true;
});
}
int counter = 0;
};
int main() {
Obj obj;
obj.load();
while(true)
for(auto i = 0; i < injections.size(); i++) {
auto pop = injections[i]();
if(pop)
injections.erase(injections.begin() + i--);
}
}
正是以这种方式运行,一切正常,但是取消注释行,它崩溃了。问题在于,在推入第二个lambda之后,this
指向一些垃圾,并且++counter
引发。我希望第一个lambda可以通过引用捕获成员,这些成员在结束load()
之后不会超出范围,这正是发生的情况。对于第二个lambda,我希望通过引用捕获引用,使counter
可用,这也是使用注释的坏行时发生的情况。看起来lambda的构造会使之后的所有内容失效。这是什么原因以及一些解决方案?
[在injections
中插入内容时,先前的std::function<bool()>
可能会移动(并被破坏)。