{"id":373,"date":"2015-10-06T22:09:44","date_gmt":"2015-10-07T04:09:44","guid":{"rendered":"http:\/\/mepem.com\/pemcode\/?p=373"},"modified":"2015-10-06T22:30:02","modified_gmt":"2015-10-07T04:30:02","slug":"c-member-function-pointer-parent-class-template-stdfunction","status":"publish","type":"post","link":"http:\/\/mepem.com\/pemcode\/?p=373","title":{"rendered":"C++ member function pointer, parent class, template, std::function"},"content":{"rendered":"<p>Today I ran into a C++ scenario where I found std::function to be useful.&#160; I wanted to create a std::queue of member function pointers to functions that are children of the same parent class.&#160; For example:<\/p>\n<div id=\"scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:094dd15b-559f-491f-866d-190081a92484\" class=\"wlWriterEditableSmartContent\" style=\"float: none; padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px\">\n<pre style=white-space:normal>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\nclass Parent\n{\npublic:\n    Parent() {};\n    virtual ~Parent() {};\n};\nclass ChildA : public Parent\n{\npublic:\n    ChildA() : Parent() {};\n    ~ChildA() {};\n    void Execute01() {printf(&quot;A&quot;);};\n    void Execute02() {printf(&quot;B&quot;);};\n    void Execute03() {printf(&quot;C&quot;);};\n};\nclass ChildB : public Parent\n{\npublic:\n    void Execute01() {printf(&quot;D&quot;);};\n    void Execute02() {printf(&quot;E&quot;);};\n    void Execute03() {printf(&quot;F&quot;);};\n};\n<\/pre>\n<\/div>\n<p>To keep it simple, this examples shows two child classes (ChildA, ChildB), but I wanted it to work for lots more child classes.&#160; I wanted to push() member function pointers to ChildA::Execute01() etc into a std::queue&#8230;&#160; But I ran into an issue.&#160; The declaration for a member function pointer requires the class to be specified, and the execution requires an instance of the class the be specified.&#160; So the following snippet is valid:<\/p>\n<div id=\"scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:ad266f64-5d75-4034-aba7-6403a0418f04\" class=\"wlWriterEditableSmartContent\" style=\"float: none; padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px\">\n<pre style=white-space:normal>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\ntypedef void (ChildA::*funcPtr)(); \nstd::queue&lt;funcPtr&gt; theQueue; \nChildA childA; \ntheQueue.push(&amp;ChildA::Execute01); \nfuncPtr fn = theQueue.front(); \n(childA.*fn)();\n<\/pre>\n<\/div>\n<p>However, I can&#8217;t push() a pointer to a ChildB member function into this same std::queue.&#160; If I try referencing the parent class as follows:<\/p>\n<div id=\"scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:37851325-e84d-4a93-a8d2-18cfb730fd07\" class=\"wlWriterEditableSmartContent\" style=\"float: none; padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px\">\n<pre style=white-space:normal>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\ntypedef void (Parent::*funcPtr)();\nstd::queue&lt;funcPtr&gt; theQueue;\nChildA childA;\ntheQueue.push(&amp;ChildA::Execute01);\nfuncPtr fn = theQueue.front();\n(childA.*fn)();\n<\/pre>\n<\/div>\n<p>Then Visual Studio 2013 gives me an error:<\/p>\n<p>Error&#160;&#160;&#160; 9&#160;&#160;&#160; error C2664: &#8216;void std::queue&lt;funcPtr,std::deque&lt;_Ty,std::allocator&lt;_Ty&gt;&gt;&gt;::push(void (__cdecl Parent::* const &amp;)(void))&#8217; : cannot convert argument 1 from &#8216;void (__cdecl ChildB::* )(void)&#8217; to &#8216;void (__cdecl Parent::* &amp;&amp;)(void)&#8217; <\/p>\n<p>Ignoring C++14&#8217;s variable templates, there are two types of templates &#8211; function templates and class templates&#8230;&#160; So we can&#8217;t just use a template on the function pointer&#8217;s typedef.&#160; Instead, my next solution was to make a queue of Delegate&#8217;s and use a template to define the delegate class&#8217;s children:<\/p>\n<style>\n<p>.keyword{color:rgb(0,0,255);}\n.comment{color:rgb(0,128,0);}\n.pp{color:rgb(0,0,255);}<\/style>\n<div id=\"scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:6d798c18-0779-470a-824f-51745d33df25\" class=\"wlWriterEditableSmartContent\" style=\"float: none; padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px\">\n<pre style=white-space:normal>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\nclass Delegate\n{\npublic:\n  Delegate() {};\n  virtual ~Delegate() {};\n  virtual void ExeFunc() = 0;\n};\ntemplate&lt;class T&gt;\nclass DelegateT : public Delegate\n{\npublic:\n  DelegateT(T* obj, void (T::*func)()) { m_obj = obj; m_func = func; };\n  ~DelegateT() {};\n  void ExeFunc() { (m_obj-&gt;*m_func)(); }\nprotected:\n  void (T::*m_func)();\n  T* m_obj;\n};\n<\/pre>\n<\/div>\n<p>And here&#8217;s an example usage:<\/p>\n<div id=\"scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:2e5ed21c-4123-4e0e-8201-e6f212e0cd34\" class=\"wlWriterEditableSmartContent\" style=\"float: none; padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px\">\n<pre style=white-space:normal>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\nstd::queue&lt;Delegate *&gt; theQueue;\nChildA childA;\nChildB childB;\ntheQueue.push(new DelegateT&lt;ChildA&gt;(&amp;childA, &amp;ChildA::Execute01));\ntheQueue.push(new DelegateT&lt;ChildB&gt;(&amp;childB, &amp;ChildB::Execute01));\nwhile (!theQueue.empty())\n{\n  Delegate *del = theQueue.front();\n  del-&gt;ExeFunc();\n  theQueue.pop();\n  delete del;\n}\n<\/pre>\n<\/div>\n<p>Finally I ran into a more modern solution (but not that modern seeing as it&#8217;s supported by Visual Studio 2010) &#8211; use std::function:<\/p>\n<div id=\"scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:1e47b484-70d4-4f1c-8531-dabb6b3e6ff1\" class=\"wlWriterEditableSmartContent\" style=\"float: none; padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px\">\n<pre style=white-space:normal>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\nChildA childA;\nChildB childB;\nstd::queue&lt;std::function&lt;void()&gt;&gt; theQueue;\ntheQueue.push(std::bind(&amp;ChildA::Execute01, childA));\ntheQueue.push(std::bind(&amp;ChildB::Execute01, childB));\nwhile (!theQueue.empty())\n{\n  std::function&lt;void()&gt; func = theQueue.front();\n  func();\n  theQueue.pop();\n}\n<\/pre>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Today I ran into a C++ scenario where I found std::function to be useful.&#160; I wanted to create a std::queue of member function pointers to functions that are children of the same parent class.&#160; For example: To keep it simple, this examples shows two child classes (ChildA, ChildB), but I wanted it to work for [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"spay_email":"","jetpack_publicize_message":"","jetpack_is_tweetstorm":false,"jetpack_publicize_feature_enabled":true},"categories":[12,8],"tags":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v17.7.1 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"http:\/\/mepem.com\/pemcode\/?p=373\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"C++ member function pointer, parent class, template, std::function - Pem&#039;s Code Blog\" \/>\n<meta property=\"og:description\" content=\"Today I ran into a C++ scenario where I found std::function to be useful.&#160; I wanted to create a std::queue of member function pointers to functions that are children of the same parent class.&#160; For example: To keep it simple, this examples shows two child classes (ChildA, ChildB), but I wanted it to work for [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"http:\/\/mepem.com\/pemcode\/?p=373\" \/>\n<meta property=\"og:site_name\" content=\"Pem&#039;s Code Blog\" \/>\n<meta property=\"article:published_time\" content=\"2015-10-07T04:09:44+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2015-10-07T04:30:02+00:00\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"mepem37\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"2 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebSite\",\"@id\":\"http:\/\/mepem.com\/pemcode\/#website\",\"url\":\"http:\/\/mepem.com\/pemcode\/\",\"name\":\"Pem&#039;s Code Blog\",\"description\":\"Game Development, Graphics Programming, GPU, Computer Science\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"http:\/\/mepem.com\/pemcode\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"http:\/\/mepem.com\/pemcode\/?p=373#webpage\",\"url\":\"http:\/\/mepem.com\/pemcode\/?p=373\",\"name\":\"C++ member function pointer, parent class, template, std::function - Pem&#039;s Code Blog\",\"isPartOf\":{\"@id\":\"http:\/\/mepem.com\/pemcode\/#website\"},\"datePublished\":\"2015-10-07T04:09:44+00:00\",\"dateModified\":\"2015-10-07T04:30:02+00:00\",\"author\":{\"@id\":\"http:\/\/mepem.com\/pemcode\/#\/schema\/person\/f608518805f74a09056a8d28a205237d\"},\"breadcrumb\":{\"@id\":\"http:\/\/mepem.com\/pemcode\/?p=373#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"http:\/\/mepem.com\/pemcode\/?p=373\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"http:\/\/mepem.com\/pemcode\/?p=373#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"http:\/\/mepem.com\/pemcode\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"C++ member function pointer, parent class, template, std::function\"}]},{\"@type\":\"Person\",\"@id\":\"http:\/\/mepem.com\/pemcode\/#\/schema\/person\/f608518805f74a09056a8d28a205237d\",\"name\":\"mepem37\",\"image\":{\"@type\":\"ImageObject\",\"@id\":\"http:\/\/mepem.com\/pemcode\/#personlogo\",\"inLanguage\":\"en-US\",\"url\":\"http:\/\/1.gravatar.com\/avatar\/7e8be16a457b4e26979bd95268bf1ec8?s=96&d=mm&r=g\",\"contentUrl\":\"http:\/\/1.gravatar.com\/avatar\/7e8be16a457b4e26979bd95268bf1ec8?s=96&d=mm&r=g\",\"caption\":\"mepem37\"},\"url\":\"http:\/\/mepem.com\/pemcode\/?author=1\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"http:\/\/mepem.com\/pemcode\/?p=373","og_locale":"en_US","og_type":"article","og_title":"C++ member function pointer, parent class, template, std::function - Pem&#039;s Code Blog","og_description":"Today I ran into a C++ scenario where I found std::function to be useful.&#160; I wanted to create a std::queue of member function pointers to functions that are children of the same parent class.&#160; For example: To keep it simple, this examples shows two child classes (ChildA, ChildB), but I wanted it to work for [&hellip;]","og_url":"http:\/\/mepem.com\/pemcode\/?p=373","og_site_name":"Pem&#039;s Code Blog","article_published_time":"2015-10-07T04:09:44+00:00","article_modified_time":"2015-10-07T04:30:02+00:00","twitter_card":"summary_large_image","twitter_misc":{"Written by":"mepem37","Est. reading time":"2 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebSite","@id":"http:\/\/mepem.com\/pemcode\/#website","url":"http:\/\/mepem.com\/pemcode\/","name":"Pem&#039;s Code Blog","description":"Game Development, Graphics Programming, GPU, Computer Science","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"http:\/\/mepem.com\/pemcode\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"en-US"},{"@type":"WebPage","@id":"http:\/\/mepem.com\/pemcode\/?p=373#webpage","url":"http:\/\/mepem.com\/pemcode\/?p=373","name":"C++ member function pointer, parent class, template, std::function - Pem&#039;s Code Blog","isPartOf":{"@id":"http:\/\/mepem.com\/pemcode\/#website"},"datePublished":"2015-10-07T04:09:44+00:00","dateModified":"2015-10-07T04:30:02+00:00","author":{"@id":"http:\/\/mepem.com\/pemcode\/#\/schema\/person\/f608518805f74a09056a8d28a205237d"},"breadcrumb":{"@id":"http:\/\/mepem.com\/pemcode\/?p=373#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["http:\/\/mepem.com\/pemcode\/?p=373"]}]},{"@type":"BreadcrumbList","@id":"http:\/\/mepem.com\/pemcode\/?p=373#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"http:\/\/mepem.com\/pemcode"},{"@type":"ListItem","position":2,"name":"C++ member function pointer, parent class, template, std::function"}]},{"@type":"Person","@id":"http:\/\/mepem.com\/pemcode\/#\/schema\/person\/f608518805f74a09056a8d28a205237d","name":"mepem37","image":{"@type":"ImageObject","@id":"http:\/\/mepem.com\/pemcode\/#personlogo","inLanguage":"en-US","url":"http:\/\/1.gravatar.com\/avatar\/7e8be16a457b4e26979bd95268bf1ec8?s=96&d=mm&r=g","contentUrl":"http:\/\/1.gravatar.com\/avatar\/7e8be16a457b4e26979bd95268bf1ec8?s=96&d=mm&r=g","caption":"mepem37"},"url":"http:\/\/mepem.com\/pemcode\/?author=1"}]}},"jetpack_featured_media_url":"","jetpack_publicize_connections":[],"jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/patRsd-61","_links":{"self":[{"href":"http:\/\/mepem.com\/pemcode\/index.php?rest_route=\/wp\/v2\/posts\/373"}],"collection":[{"href":"http:\/\/mepem.com\/pemcode\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/mepem.com\/pemcode\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/mepem.com\/pemcode\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/mepem.com\/pemcode\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=373"}],"version-history":[{"count":4,"href":"http:\/\/mepem.com\/pemcode\/index.php?rest_route=\/wp\/v2\/posts\/373\/revisions"}],"predecessor-version":[{"id":377,"href":"http:\/\/mepem.com\/pemcode\/index.php?rest_route=\/wp\/v2\/posts\/373\/revisions\/377"}],"wp:attachment":[{"href":"http:\/\/mepem.com\/pemcode\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=373"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/mepem.com\/pemcode\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=373"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/mepem.com\/pemcode\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=373"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}