Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>You need another template parameter, because you care about two different classes - the type of the pointer (and hence the member function you're going to call with it), and the type of the container:</p> <pre><code>#include &lt;list&gt; struct AirplaneType { }; struct Airplane : AirplaneType { int check() const { return 3; } }; template &lt;typename T, typename U, typename I&gt; void add(T* element, std::list&lt;U*&gt; &amp; container, I (T::*f)() const) { container.push_back(element); I i = (element-&gt;*f)(); } int main() { std::list&lt;AirplaneType*&gt; ls; Airplane a; add(&amp;a, ls, &amp;Airplane::check); } </code></pre> <p>In this case my <code>add</code> function doesn't really use the fact that <code>container</code> is a <code>list</code>, so a more sensible version might be:</p> <pre><code>template &lt;typename T, typename U, typename I&gt; void add(T* element, U &amp; container, I (T::*f)() const) { container.push_back(element); I i = (element-&gt;*f)(); } </code></pre> <p>And then again, you could abstract further:</p> <pre><code>template &lt;typename T, typename U, typename AUF&gt; void add(T element, U &amp; container, AUF func) { container.push_back(element); typename AUF::result_type i = func(element); } </code></pre> <p>... but that's slightly less convenient for the caller:</p> <pre><code>#include &lt;functional&gt; add(&amp;a, ls, std::mem_fun(&amp;Airplane::check)); </code></pre> <p><i>Any suggestions for good practice?</i></p> <p>Don't create containers of raw pointers.</p> <p>Edit: to get this working with a virtual function, with each of my options:</p> <pre><code>#include &lt;list&gt; #include &lt;functional&gt; #include &lt;iostream&gt; struct AirplaneType { virtual int check() const { return 0; } }; struct Airplane : AirplaneType { int check() const { std::cout &lt;&lt; "check\n"; return 3; } }; template &lt;typename T, typename U, typename I&gt; void add(U* element, std::list&lt;T*&gt; &amp; container, I (U::*f)() const) { container.push_back(element); I i = (element-&gt;*f)(); } template &lt;typename T, typename U, typename AUF&gt; void add2(T element, U &amp; container, AUF func) { container.push_back(element); typename AUF::result_type i = func(element); } int main() { std::list&lt;AirplaneType*&gt; ls; Airplane a; add(static_cast&lt;AirplaneType*&gt;(&amp;a), ls, &amp;AirplaneType::check); add2(&amp;a, ls, std::mem_fun(&amp;AirplaneType::check)); } </code></pre> <p>Output is:</p> <pre><code>check check </code></pre> <p>which shows that the override is correctly called even though the function pointer was taken to <code>AirplaneType::check</code>, not <code>Airplane::check</code>.</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