我有以下示例:
#include <iostream>
#include <functional>
struct Tmr {
typedef std::function<void(void)> Callback;
Callback cb;
Tmr(Callback cb_) :
cb( cb_ )
{
}
void timeout()
{
cb();
}
};
struct Obj {
struct Tmr t;
Obj() :
t( std::ref( *this ) )
{
}
void operator () ()
{
std::cout << __func__ << '\n';
}
};
int main(int argc, char *argv[])
{
Obj o;
o.t.timeout();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
运行正常,但最初我有以下构造函数Obj:
Obj() :
t( *this )
Run Code Online (Sandbox Code Playgroud)
这导致运行时错误.我想这是因为只有对成员函数的引用存储在我的回调中,而不是调用成员的对象.
我不明白的是std::ref,当我这样做Obj() : t(std::ref(*this))以及为什么这会让程序运行起来.任何人都可以了解正在发生的事情以及它是如何运作的?
当您没有通过引用传递时,您在初始化*this之前t进行复制- 这意味着您在初始化之前复制t及其回调成员,这是未定义的行为.
(并且复制构造函数std::function可能会尝试复制未初始化指针所指向的内容,这是导致实际崩溃的原因.)