Boost::Signal inside a std::map

This post is very old. Please bear in mind that information here might be incorrect or obsolete, and links can be broken. If something seems wrong, please feel free to comment or contact me and I'll update the post.

Recently, I came across a problem with Boost::Signal. I wanted to use them inside a std::map so I could map signals to categories, and this turned out to be not as simple as one might think.

Problem

The main problem is that boost::signal is noncopyable, meaning you can’t use the assignment operator “=” at all. This prevents the straightforward use in any STL container, as those depend on the assignment operator. You can of course have explicit instances of boost::signal, but you can’t use them directly in a container, let alone add and remove them dynamically.

Solution

The first solution I tried was to store pointers (in my case, boost::shared_ptr<>) to the signals, and fill the map with those. This works, but it is a bit cumbersome to maintain all the pointers and have new all around the place. Fortunately, another boost library comes to the rescue, boost::ptr_map from the Boost Pointer Container library. It has two specialities I came across (using boost 1.33.1 beta from 8th November).

  • Its insert () function takes a non-const reference as key, unlike the std::map. Be aware of that, as it can lead to hard-to-find compiler errors.
  • The dereferencing was non-standard, in my case I had to use (iterator_to_ptr_map)(params_for_signal), I supposed I would have to add some “*” somewhere but somehow the map didn’t need it.

Will try with Boost 1.33.1 final and report if there is any difference to the beta.

Related posts:

  1. Boost 1.34.1 released
  2. Bug in Boost 1.35/Threads, Condition::notify_one
  3. Boost 1.35 released

This entry was posted in Programming and tagged , . Bookmark the permalink.

4 Responses to Boost::Signal inside a std::map

  1. Anteru says:

    No difference with Boost 1.33.1 final :)

  2. Ulysses says:

    Could someone explain, why boost::signal is noncopyable!?!?

  3. Anteru says:

    Take a look at the rationale at http://boost.org/doc/html/signals.html, specifically at “trackable copying behavior”.

    Basically, if you copy a signal, how to you inform those who are registered that they are now registered at a new signal? There is no way to do this reliably.

  4. Vladimir says:

    When i faced with a problem that boost::signal is noncopyable then i used dynamic object.
    typedef boost::signal signal_exec;
    typedef boost::signals::connection sign_conn;

    // creating and setting to the std::map
    std::map::iterator it;
    sign_conn s_c;

    it = ExecHandlers.find(id);
    if (it != ExecHandlers.end()) {
    FLD_LOG(LOG_ERROR, “exec id = %d already exist”, id);
    } else {
    signal_exec *exec = new signal_exec();
    s_c = exec->connect(exec_handler);
    if (!s_c.connected()) {
    FLD_LOG(LOG_ERROR, “SetExecHandler failed”);
    } else {
    ExecHandlers.insert(std::make_pair(id, exec));
    }
    }
    return s_c;
    }
    using:
    std::map::iterator it;
    it = ExecHandlers.find(sql.id);
    if (it == ExecHandlers.end()) {
    FLD_LOG(LOG_ERROR, “exec id = %d not found in FireExecHandler”, sql.id);
    } else {
    (*it->second) (res, error, sql); // calling
    }

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>