Storing a boost::signals2 signal in a map?

1.7k views Asked by At

I am facing the following problem: I want to store a number of boost::signals2 signal variables in a map. Since these signals are non-copyable, this obviously will not work. How can I work around this? I have already found this older question. In it, a poster suggests storing the signals as a shared_ptr. Is this the only way of doing it? Does it have any drawbacks, or, more important, is it safe?

3

There are 3 answers

0
Gnosophilon On BEST ANSWER

As has been pointed out by some commentators: Using shared_ptrs for signals is perfectly safe. My implementation works and has been thoroughly tested in the meantime and I am happy to report that there are indeed no problems :)

0
Boris Lyubimov On

Since it's non-copyable and non-movable(may be it has changed on latest revision). For std::map if you don't want to use shared_ptr you can use operator[] instead of insert or emplace methods since operator[] constructs mapped_type if key_value doesn't exist. Obviously it doesn't solve problem when you want to add signal with previously assigned slots.

typedef boost::signal2... Signal;
std::map<int, Signal> sigmap;
sigmap[1]; // constructs signal using default constructor
sigmap[2].connect(slot); // constructs signal and connects slot
0
Emile Cormier On

If the signals are not intended to be shared, you can store boost::signal objects allocated on the heap inside a Boost Pointer Container:

Boost.Pointer Container provides containers for holding heap-allocated objects in an exception-safe manner and with minimal overhead.

A boost pointer container stores pointers to its elements and automatically deletes those heap objects when necessary. The API tries to hide the fact that elements are stored by pointer and returns element references whenever possible.

Example:

#include <iostream>
#include <map>
#include <string>
#include <boost/ptr_container/ptr_map.hpp>
#include <boost/signals.hpp>

void foo() {std::cout << "foo\n";}

void bar() {std::cout << "bar\n";}

int main()
{
    typedef boost::signal<void ()> Signal;
    boost::ptr_map< std::string, Signal> sigmap;
    sigmap["foo"].connect(&foo);
    sigmap["bar"].connect(&bar);
    sigmap["foo"](); // emit signal associated with "foo"
    sigmap["bar"](); // emit signal associated with "bar"
}