Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>I once solved this by simulating .NET delegates:</p> <pre><code>template&lt;typename T&gt; class Delegate { //static_assert(false, "T must be a function type"); }; template&lt;typename ReturnType&gt; class Delegate&lt;ReturnType()&gt; { private: class HelperBase { public: HelperBase() { } virtual ~HelperBase() { } virtual ReturnType operator()() const = 0; virtual bool operator==(const HelperBase&amp; hb) const = 0; virtual HelperBase* Clone() const = 0; }; template&lt;typename Class&gt; class Helper : public HelperBase { private: Class* m_pObject; ReturnType(Class::*m_pMethod)(); public: Helper(Class* pObject, ReturnType(Class::*pMethod)()) : m_pObject(pObject), m_pMethod(pMethod) { } virtual ~Helper() { } virtual ReturnType operator()() const { return (m_pObject-&gt;*m_pMethod)(); } virtual bool operator==(const HelperBase&amp; hb) const { const Helper&amp; h = static_cast&lt;const Helper&amp;&gt;(hb); return m_pObject == h.m_pObject &amp;&amp; m_pMethod == h.m_pMethod; } virtual HelperBase* Clone() const { return new Helper(*this); } }; HelperBase* m_pHelperBase; public: template&lt;typename Class&gt; Delegate(Class* pObject, ReturnType(Class::*pMethod)()) { m_pHelperBase = new Helper&lt;Class&gt;(pObject, pMethod); } Delegate(const Delegate&amp; d) { m_pHelperBase = d.m_pHelperBase-&gt;Clone(); } Delegate(Delegate&amp;&amp; d) { m_pHelperBase = d.m_pHelperBase; d.m_pHelperBase = nullptr; } ~Delegate() { delete m_pHelperBase; } Delegate&amp; operator=(const Delegate&amp; d) { if (this != &amp;d) { delete m_pHelperBase; m_pHelperBase = d.m_pHelperBase-&gt;Clone(); } return *this; } Delegate&amp; operator=(Delegate&amp;&amp; d) { if (this != &amp;d) { delete m_pHelperBase; m_pHelperBase = d.m_pHelperBase; d.m_pHelperBase = nullptr; } return *this; } ReturnType operator()() const { (*m_pHelperBase)(); } bool operator==(const Delegate&amp; d) const { return *m_pHelperBase == *d.m_pHelperBase; } bool operator!=(const Delegate&amp; d) const { return !(*this == d); } }; </code></pre> <p>You can use it much like .NET delegates:</p> <pre><code>class A { public: void M() { ... } }; class B { public: void M() { ... } }; A a; B b; Delegate&lt;void()&gt; d = Delegate&lt;void()&gt;(&amp;a, &amp;A::M); d(); // calls A::M d = Delegate&lt;void()&gt;(&amp;b, &amp;B::M); d(); // calls B::M </code></pre> <p>This works with methods that have no arguments. If you can use C++11, you can modify it to use variadic templates to handle any number of parameters. Without C++11, you need to add more Delegate specializations to handle specific numbers of parameters:</p> <pre><code>template&lt;typename ReturnType, typename Arg1&gt; class Delegate&lt;ReturnType(Arg1)&gt; { ... }; template&lt;typename ReturnType, typename Arg1, typename Arg2&gt; class Delegate&lt;ReturnType(Arg1, Arg2)&gt; { ... }; </code></pre> <p>With this Delegate class you can also emulate .NET events, which are based on delegates.</p>
 

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