Note that there are some explanatory texts on larger screens.

plurals
  1. POPointer-to-member-func, template & inheritance mixup
    primarykey
    data
    text
    <p>I am trying to create a generic "callback" object that will hold arbitrary data and invoke member functions of related classes. Due to internal policy, I cannot use Boost.</p> <p>The callback object looks like this:</p> <pre><code>template&lt;typename Object, typename Data&gt; class Callback { public: typedef void (Object::*PHandler)(Callback*); Callback(Object* obj, PHandler handler) : pObj(obj), pHandler(handler) {} Callback&amp; set(PHandler handler) { pHandler = handler; return *this; } void run() { (pObj-&gt;*pHandler)(this); } public: Data data; protected: Object* pObj; PHandler pHandler; }; </code></pre> <p>And the class it works on:</p> <pre><code>struct Object1 { struct Data { int i; }; typedef Callback&lt;Object1, Data&gt; Callback1; void callback(Callback1* pDisp) { printf("%cb\n", pDisp-&gt;data.i); } void test() { Callback1 cb(this, &amp;Object1::callback); cb.data.i = 1; cb.run(); } }; </code></pre> <p>The following test works as expected:</p> <pre><code>Object1 obj1; obj1.test(); </code></pre> <p>So far so good.</p> <p>However, when a coworker tried to derive from the <code>Callback</code> class instead of using a <code>typedef</code>, they got compilation errors due to incompatible pointers:</p> <pre><code>struct Object2 { struct Data { int i; Data(int j) { i = j; } }; class Callback2 : public Callback&lt;Object2, Data&gt; { Callback2(Object2* obj, PHandler handler, int i) : Callback(obj, handler) { data.i = i; } }; void callback(Callback2* pDisp) { printf("%cb\n", pDisp-&gt;data.i); } void test() { Callback2 cb(this, &amp;Object2::callback, 2); cb.run(); } }; </code></pre> <p>I tried using the "curiously recurring template pattern" in the Callback class and managed to get derived classes working, but it broke code that used the <code>typedef</code> method.</p> <p>My question is:</p> <p><em>How can I modify the</em> <code>Callback</code> <em>class to work with both cases, and without requiring extra work on the part of the user of the class?</em></p>
    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.
 

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