How to copy the slots of a boost signal

1.4k views Asked by At

Is there a way to get the slots a signal connected to? i.e, i want to copy the slots of a signal from one instance of a class to another

I have a signal in my class and run into the following error. This is probably because this class is used in STL containers.

1>c:\boost_1_52_0\boost\signals\detail\signal_base.hpp(150): error C2248: 'boost::noncopyable_::noncopyable::noncopyable' : cannot access private member declared in class 'boost::noncopyable_::noncopyable'
1>          c:\boost_1_52_0\boost\noncopyable.hpp(27) : see declaration of 'boost::noncopyable_::noncopyable::noncopyable'
1>          c:\boost_1_52_0\boost\noncopyable.hpp(22) : see declaration of 'boost::noncopyable_::noncopyable'
1>          This diagnostic occurred in the compiler generated function 'boost::signals::detail::signal_base::signal_base(const boost::signals::detail::signal_base &)'
1>  test.cpp

so, i decided to put a copy constructor and connect the signal to the slots of the parameter signal and then i get the following error,

1>d:\workarea\boostsignalsEx\test.h(26): error C2663: 'boost::signal1<R,T1>::connect' : 2 overloads have no legal conversion for 'this' pointer
1>          with
1>          [
1>              R=void,
1>              T1=int
1>          ]

If i remove the const qualifier for the copy constructor parameter, I get another error..

1>d:\workarea\boostsignalsEx\test.h(40): error C2558: class 'test' : no copy constructor available or copy constructor is declared 'explicit'

This is the sample code I'm working on

class test{
public:
boost::signal1<void, int> sig;
test(const test& t) { t.sig.connect(sig);}; 
void attach(boost::function1<void, int> f) {sig.connect(f);}
};

guess chaining the signals will not work because i am not sure if the copy constructor parameter object will out live "this" object

2

There are 2 answers

0
ProgramCpp On BEST ANSWER

The Boost signals are non-copyable by design and thus cannot be used in STL containers. pointers to signals can be used instead as mentioned in this Blog.

The signals are made movable which can be used in c++11 containers.

1
sehe On

You just connect the signal to the new target:

See it Live on Coliru

#include <boost/signals2.hpp>

typedef void(Sigature)(int);
typedef boost::signals2::signal<Sigature> Signal;
typedef Signal::slot_type                 SlotType;

class test{
    public:
        Signal sig;

        test() = default;
        test(const test& other) { *this = other; };

        test& operator=(test const& other) { sig.connect(other.sig); return *this; }

        void attach(SlotType const& f)   { sig.connect(f); }
        void trigger(int i) const        { sig(i); }
};

int main()
{
    test a, b;
    a.attach([](int i) { std::cout << "subscribed to a:      " << i << "\n"; });
    a.attach([](int i) { std::cout << "also subscribed to a: " << i << "\n"; });

    std::cout << "Trigger via a:\n";
    a.trigger(42);

    b = a;

    std::cout << "\nNow via b:\n";
    b.trigger(43);
}

Prints

Trigger via a:
subscribed to a:      42
also subscribed to a: 42

Now via b:
subscribed to a:      43
also subscribed to a: 43