以下代码
#include <functional>
#include <iostream>
class State {
void first_shot()
{
std::cout << "foo start " << this << std::endl;
this->x = [=]()
{
std::cout << "baz " << this << std::endl;
};
std::cout << "foo end " << this << std::endl;
}
public:
std::function<void()> x;
State()
{
this->x = [=]()
{
std::cout << "bar start " << this << std::endl;
this->first_shot();
/* HERE */
std::cout << "bar end " << this << std::endl;
};
}
};
int main()
{
State s;
s.x();
s.x();
return 0;
}
使用g++ -std=c++0x
进行编译时,非常奇怪。在评论HERE
之后的行中,this
变为空指针。实际上,只要this->x
在this->first_shot()
期间更改为空函数指针或绑定到任何其他函数,this
将在调用后更改为null。
我在Ubuntu 14.04 x64和CentOS 7(都是g ++ 4.8.2)下进行了测试。使用clang ++进行编译时,它不可重现(this
指针不会改变)。
这是对std::function
的误用吗?当函数对象被销毁时,绑定到它的值(在这种情况下为this
)变得无效,这是相当可观的。
所以我想通过对后一个lambda
的简单修改来解决这个问题this->x = [=]()
{
State* me = this;
std::cout << "bar start " << me << std::endl;
me->first_shot();
std::cout << "bar end " << me << std::endl;
};
固定代码没问题,不是吗?
顺便说一下,在我编译之前使用g ++运行它,二进制clang ++生成运行没有任何问题,即使使用valgrind也不会出现内存错误。我想知道clang是怎么做的“恰到好处”(它恰到好处吗?)