Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>If the function is not <code>static</code>, you cannot pass it in input to a function that accepts a non-member function pointer. </p> <p>Consider that a non-<code>static</code> member function has an implicit pointer to <code>ClassName</code> as its first parameter, which points to the object on which the member function is being invoked.</p> <pre><code>struct X { static void foo() { } // Does not have an implicit "this" pointer argument void bar() { } // Has an implicit "this" pointer argument }; int main() { void (*f)() = &amp;X::foo; // OK: foo is static void (*g)() = &amp;X::bar; // ERROR! bar is non-static } </code></pre> <p>Here, not even <code>std::bind()</code> will work, because the result is not convertible to a function pointer. Lambdas are convertible to function pointers, but only if they are non-capturing (and a lambda here would need to capture the object to invoke the member function on).</p> <p>Therefore, the only (ugly) workaround is to have a global adapter function which invokes the member function on an object which is available through a global pointer variable. The global pointer variable is set prior to calling the function:</p> <pre><code>struct X { void bar() { } }; void function_taking_a_function_pointer(void (*f)()) { // Do something... f(); } X* pX = nullptr; void bar_adapter() { pX-&gt;bar(); } int main() { X x; // Some object I want to invoke the member function bar() on... pX = &amp;x; // Set the global pointer and invoke the function... function_taking_a_function_pointer(bar_adapter); } </code></pre> <p>If you want, you can make this slightly more flexible by turning <code>bar_adapter</code> into a function <em>template</em>, and passing the pointer-to-member-function as a template argument:</p> <pre><code>template&lt;typename T, void (T::*mf)()&gt; void adapter() { (pX-&gt;*mf)(); } </code></pre> <p>Here is how you would use it:</p> <pre><code>#include &lt;iostream&gt; struct X { void foo() { std::cout &lt;&lt; "X::foo()" &lt;&lt; std::endl; } void bar() { std::cout &lt;&lt; "X::bar()" &lt;&lt; std::endl; } }; void function_taking_a_function_pointer(void (*f)()) { // Do something... f(); } X* pX = nullptr; template&lt;typename T, void (T::*mf)()&gt; void adapter() { (pX-&gt;*mf)(); } int main() { X x; // Some object I want to invoke the member function bar() on... pX = &amp;x; // Set the global pointer and invoke the function(s)... function_taking_a_function_pointer(adapter&lt;X, &amp;X::foo&gt;); function_taking_a_function_pointer(adapter&lt;X, &amp;X::bar&gt;); } </code></pre> <p>Finally, here is a <a href="http://liveworkspace.org/code/41HfPq%2438" rel="nofollow">live example</a>.</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.
    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.
    3. 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