Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Here is an approach based on making a <code>std::multimap</code> from the <code>std::type_index</code> of the function to a <code>std::function</code> of the appropriate type:</p> <pre><code>#include &lt;functional&gt; #include &lt;iostream&gt; #include &lt;map&gt; #include &lt;memory&gt; #include &lt;typeindex&gt; void freestanding() { std::cout &lt;&lt; "freestanding" &lt;&lt; std::endl; } void freestandingInt(int iArg) { std::cout &lt;&lt; "freestandingInt " &lt;&lt; iArg &lt;&lt; std::endl; } // Base class for all functions so that we can store all functions // in a single container. struct Function { virtual ~Function() { } }; // Derived class template for functions with a particular signature. template &lt;typename T&gt; struct BasicFunction : Function { std::function&lt;T&gt; function; BasicFunction(std::function&lt;T&gt; function) : function(function) { } }; // Generic container of listeners for any type of function typedef std::multimap&lt;std::type_index,std::unique_ptr&lt;Function&gt; &gt; Listeners; template &lt;typename Func&gt; static void addListener(Listeners &amp;listeners,Func &amp;function) { std::type_index index(typeid(Func)); std::unique_ptr&lt;Function&gt; func_ptr(new BasicFunction&lt;Func&gt;(std::function&lt;Func&gt;(function))); listeners.insert(Listeners::value_type(index,std::move(func_ptr))); } template &lt;typename... Args&gt; static void callListeners(const Listeners &amp;listeners,Args&amp;&amp;... args) { typedef void Func(typename std::remove_reference&lt;Args&gt;::type...); std::type_index index(typeid(Func)); Listeners::const_iterator i = listeners.lower_bound(index); Listeners::const_iterator j = listeners.upper_bound(index); for (;i!=j; ++i) { const Function &amp;f = *i-&gt;second; std::function&lt;Func&gt; func = static_cast&lt;const BasicFunction&lt;Func&gt; &amp;&gt;(f).function; func(std::forward&lt;Args&gt;(args)...); } } struct Dispatcher { typedef struct Event_ { Listeners listeners; } Event; template&lt;class... Args&gt; void dispatch(int eventNr, Args&amp;&amp;... args) { callListeners(events[eventNr].listeners,std::forward&lt;Args&gt;(args)...); } std::map&lt;int, Event&gt; events; }; int main (int argc, char **argv) { Dispatcher disp; addListener(disp.events[0].listeners,freestanding); addListener(disp.events[0].listeners,freestandingInt); disp.dispatch(0,5); } </code></pre> <p>Output:</p> <pre><code>freestandingInt 5 </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload