Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6934611
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 27, 20262026-05-27T11:58:59+00:00 2026-05-27T11:58:59+00:00

I’d like to use boost::signals2 to handle event notification in my C++ app. I’m

  • 0

I’d like to use boost::signals2 to handle event notification in my C++ app. I’m hoping to implement something with similar functionality to browser DOM events, specifically the ability to stop the propagation of an event so that the current receiver is the last one to know about a signal and subsequent receivers are not called. (see http://www.w3.org/TR/DOM-Level-3-Events/#events-event-type-stopImmediatePropagation for more on how this works in browsers)

I have a hypothetical App class with a signal called thingHappened. It’s likely there’ll only be one App instance, with several other Widget classes of varying types that will connect to thingHappened to receive ThingEvent notifications. Sometimes the widget would like to consume (stop) the ThingEvent so that no other Widgets are notified.

At first I wondered if I could achieve this with a shared_connection_block but now I understand that this only suppresses one connection at a time. Initially I passed a shared_ptr<ThingEvent> to my signal but once the signal was called there was no way to intervene with its propagation. If I pass a shared_ptr I could have signal receivers check a value on the event and return if it’s set, but I don’t want to push that detail off to users of my library.

The solution I’ve found is to pass a ThingEvent on the stack so that it is copied for each receiver. If I set mStopPropagation on the event then when it is destroyed I can throw an exception and the signal calls terminate. The downside to this is that I need my own try/catch at the point where the signal is called, and stylistically it means I’m using an exception for an unexceptional purpose. Is there a better way?

Here’s my hypothetical App class, with a signal thingHappened:

class App
{
public:
    boost::signals2::signal<void (class ThingEvent)> thingHappened;
};

My ThingEvent class, with some data about the event (e.g. type) and an mStopPropagation property that will cause an exception to be thrown if it is set in the destructor:

class ThingEvent
{
public:
    ThingEvent(string type): mType(type), mStopPropagation(false) { }

    ~ThingEvent() 
    {
        if (mStopPropagation) {
            throw exception();
        }
    }

    void stopPropagation() { mStopPropagation = true; }

    string getType() { return mType; }

private:
    string mType;
    bool mStopPropagation;

};

Here’s a sample signal consumer, a Widget, that will call stopPropagation() on an event if the type is "goat":

class Widget
{
public:
    Widget(string name): mName(name) {}

    ~Widget() {}

    void thingHappened(ThingEvent thing)
    { 
        cout << thing.getType() << " thingHappened in widget " << mName << endl; 

        if (thing.getType() == "goat") {
            thing.stopPropagation();
        }
    }

    string getName() 
    {
        return mName;
    }

private:
    string mName;
};

Finally, here’s a quick main() function that uses these classes:

int main()
{
    App app;

    Widget w1("1");
    Widget w2("2");
    Widget w3("3");

    boost::signals2::connection c1 = app.thingHappened.connect(boost::bind(&Widget::thingHappened, &w1, _1));
    boost::signals2::connection c2 = app.thingHappened.connect(boost::bind(&Widget::thingHappened, &w2, _1));
    boost::signals2::connection c3 = app.thingHappened.connect(boost::bind(&Widget::thingHappened, &w3, _1));

    // all three widgets will receive this
    app.thingHappened(ThingEvent("otter"));

    {
        // suppress calls to c2
        boost::signals2::shared_connection_block block(c2,true);
        // only w1 and w3 will receive this
        app.thingHappened(ThingEvent("badger"));
    }

    // Widgets call ThingEvent::stopPropagation() if the type is "goat"
    try {
        // only w1 will receive this
        app.thingHappened(ThingEvent("goat"));
    } catch (exception &e) {
        // ThingEvent's destructor throws if mStopPropagation is true
        std::cout << "exception thrown by thingHappened(goat)" << std::endl;
    }

    return 0;
}

If you have boost to hand (I’m using 1.44) and you want to compile it, the full code and Makefile are at https://gist.github.com/1445230

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-27T11:58:59+00:00Added an answer on May 27, 2026 at 11:58 am

    You can do this with a custom signal combiner. These are explained in the “Signal Return Values (Advanced)” section of the boost.signals tutorial: http://www.boost.org/doc/libs/1_48_0/doc/html/signals/tutorial.html#id3070223

    Here’s the gist of it:

    struct MyCombiner {
        typedef bool result_type;
        template <typename InputIterator> result_type operator()(InputIterator aFirstObserver, InputIterator aLastObserver) const {
            result_type val = false;
            for (; aFirstObserver != aLastObserver && !val; ++aFirstObserver)  {
                val = *aFirstObserver;            
            }
            return val;
        }
    };
    

    The input iterators to operator() refer to the collection of slots for the signal. Each time you dereference one of the iterators, it calls the slot. So you can let one of the slots return a value to indicate that it doesn’t want any further slots to be called.

    Then you just pass it in to the second template arg of your signal:

    boost::signals2::signal<bool(ThingEvent), MyCombiner> sig;
    

    Now you can implement thingHappened to return a bool value indicating whether or not you want the signal to be stopped.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have a string like this: La Torre Eiffel paragonata all&#8217;Everest What PHP function
For some reason, after submitting a string like this Jack’s Spindle from a text
link Im having trouble converting the html entites into html characters, (&# 8217;) i
I am trying to understand how to use SyndicationItem to display feed which is
I've got a string that has curly quotes in it. I'd like to replace
I would like to run a str_replace or preg_replace which looks for certain words
I am trying to render a haml file in a javascript response like so:
I want use html5's new tag to play a wav file (currently only supported
I would like to count the length of a string with PHP. The string
I'm parsing an RSS feed that has an &#8217; in it. SimpleXML turns this

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.