Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using t( *this ) results RuntimeError, while t( std::ref( *this ) does not

Tags:

c++

I have the following example:

#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;
}

This runs fine, but initially I had the constructor of Obj as:

Obj() :
    t( *this )

Which results in a runtime error. I guess this is because only a reference to the member function is stored in my callback, and not the object to call the member on.

What I don't understand is what std::ref does when I do Obj() : t(std::ref(*this)) and why this makes the program work. Can anyone shed some light on what's going on and how it works ?

like image 515
binary01 Avatar asked Jan 16 '16 11:01

binary01


1 Answers

When you don't pass by reference you're copying *this before t has been initialised - which means you're copying t and its callback member before they've been initialised, which is undefined behaviour.

(And the copy constructor of std::function is likely to try to copy what's pointed to by an uninitialised pointer, which is what causes the actual crash.)

like image 91
Alan Stokes Avatar answered Oct 12 '22 11:10

Alan Stokes