2

I was wondering if somehow it was possible to connect a pointer to a boost::signals2::signal. For my problem is the following : I want the object connected to the "signal" to be changed. For instance :

class Something
{
    public:
        int x;
        bool operator()(std::string str)
        {
            std::cout << str << x << std::endl;
            return true;
        }
};


int main()
{
    boost::signals2::signal<bool (std::string)> sig;
    Something something;
    something.x = 3;
    Something* somethingElse = new Something;
    somethingElse->x = 3;
    sig.connect(something);
    sig.connect(*somethingElse); 

    something.x = 2;
    somethingElse->x = 2;

    sig("x is : ");
}

The code will always output :

x is : 3

and I would like it to output

x is : 2

Now I feel like I am missing something, either an easy solution, or a good understanding of what the boost::signals2 are for.

Nicolas Mattia
  • 1,269
  • 11
  • 20

2 Answers2

4

You just need to ref-wrap the functor you want to pass by reference (note that you will have to ensure the signal is disconnected before the functor goes out of scope).

Something something;
something.x = 3;

Something somethingElse;
somethingElse.x = 3;

sig.connect(something);
sig.connect(boost::ref(somethingElse)); 

something.x = 2;
somethingElse.x = 2;

sig("x is : ");

This will print

x is : 3
x is : 2

See it Live On Coliru

sehe
  • 374,641
  • 47
  • 450
  • 633
  • 1
    Well, that's perfect. Surprising they didn't mention it in the Signals2 doc. Is it well known among boost-users? – Nicolas Mattia Sep 26 '14 at 13:57
  • I think it's well known from boost bind (and std::bind in c++11), async, thread and similar. So yes I made the connection without needing the documentation. It's true that is worth documenting as it's specific support that's part of the public interface of the library. – sehe Sep 26 '14 at 20:24
  • Having just spent hours trying to understand why a signal emitted from inside the slot of another functor failed I would highly recommend that the docs be updated to explain the need for boost::ref. – sgbirch May 06 '17 at 16:34
0

In c++ standard way to store objects is "by value". This means that a copy of the original value is created by holder to avoid dependency on lifetime of original value. If you need to store a pointer or reference to an object you should create a proxy holder with explicit reference capture and ensure that the reference will outlive holder. This is often accomplished with boost::bind which in c++11 is available as std::bind and the modern way is to use lambda functions with capture by reference. A good example of using bind with signals was given in this answer.

Community
  • 1
  • 1
dewaffled
  • 2,850
  • 2
  • 17
  • 30