{"id":77,"date":"2012-09-25T13:29:12","date_gmt":"2012-09-25T20:29:12","guid":{"rendered":"http:\/\/martinecker.com\/martincodes\/?p=77"},"modified":"2012-09-25T19:22:19","modified_gmt":"2012-09-26T02:22:19","slug":"lambda-expression-overloading","status":"publish","type":"post","link":"http:\/\/martinecker.com\/martincodes\/lambda-expression-overloading\/","title":{"rendered":"C++11 Lambda Expression Overloading"},"content":{"rendered":"<p>I recently read about a neat trick regarding overloading of lambda expressions in C++ in a blog post by Dave Abrahams <a href=\"http:\/\/cpp-next.com\/archive\/2012\/09\/unifying-generic-functions-and-function-objects\/\" target=\"_blank\">here<\/a>. This technique was originally described by Mathias Gaunard. I want to do a short post about it here so I don't forget it.<\/p>\n<p>In C++11, it is possible to overload lambda expressions by creating a helper function object class that inherits from the function objects the compiler generates for the lambda expressions and then pulling in the lambda expressions' operator() via using declarations.<\/p>\n<h2>Simple Example<\/h2>\n<p>Here's a simple console application that demonstrates this for two lambda expressions:<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\n#include &lt;iostream&gt;\r\n\r\ntemplate &lt;class F1, class F2&gt;\r\nstruct overload_set : F1, F2\r\n{\r\n\toverload_set(F1 f1, F2f2)\r\n\t\t: F1(f1), F2(f2)\r\n\t{}\r\n\r\n\tusing F1::operator();\r\n\tusing F2::operator();\r\n};\r\n\r\ntemplate &lt;class F1, class F2&gt;\r\noverload_set&lt;F1, F2&gt; overload(F1 f1, F2 f2)\r\n{\r\n\treturn overload_set&lt;F1, F2&gt;(f1, f2);\r\n}\r\n\r\nint main(int argc, const char* argv[])\r\n{\r\n\tauto f = overload\r\n\t\t(\r\n\t\t\t[]() { return 1; },\r\n\t\t\t[](int x) { return x + 1; }\r\n\t\t);\r\n\r\n\tint x = f();\r\n\tint y = f(2);\r\n\r\n\tstd::cout &lt;&lt; &quot;x = &quot; &lt;&lt; x &lt;&lt; &quot;, y = &quot; &lt;&lt; y &lt;&lt; std::endl;\r\n\r\n\treturn 0;\r\n}\r\n<\/pre>\n<p>The overload function in this example returns a function object called overload_set that inherits from the two function objects created by the compiler for the two lambda expressions passed to it. Note that you don't necessarily have to use lambda expressions. Any function object class that exposes an operator() can be used.<\/p>\n<p>The two operator() are then pulled into the overload_set class via a using declaration. So client code now sees a function object class that provides two operator(), in this case, one that has no arguments and one that has an integer argument. When calling through the function object regular function overloading comes into play and the compiler chooses the correct function to call depending on the supplied arguments.<\/p>\n<h2>Variadic Template Implementation<\/h2>\n<p>Here's a more general implementation of the technique described above using variadic templates. If you're not yet familiar with C++11 variadic templates, the <a href=\"http:\/\/en.wikipedia.org\/wiki\/Variadic_template\" target=\"_blank\">Wikipedia page<\/a> on the subject is pretty good.<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\ntemplate &lt;class... Fs&gt; struct overload_set;\r\n\r\ntemplate &lt;class F1, class... Fs&gt;\r\nstruct overload_set&lt;F1, Fs...&gt; : F1, overload_set&lt;Fs...&gt;::type\r\n{\r\n\ttypedef overload_set type;\r\n\r\n\toverload_set(F1 head, Fs... tail)\r\n\t\t: F1(head), overload_set&lt;Fs...&gt;::type(tail...)\r\n\t{}\r\n\r\n\tusing F1::operator();\r\n\tusing overload_set&lt;Fs...&gt;::type::operator();\r\n};\r\n\r\ntemplate &lt;class F&gt;\r\nstruct overload_set&lt;F&gt; : F\r\n{\r\n\ttypedef F type;\r\n\tusing F::operator();\r\n};\r\n\r\ntemplate &lt;class... Fs&gt;\r\ntypename overload_set&lt;Fs...&gt;::type overload(Fs... x)\r\n{\r\n\treturn overload_set&lt;Fs...&gt;(x...);\r\n}\r\n<\/pre>\n<p>This is quite a neat trick, even though admittedly it probably won't be useful very often. It might come in handy for certain generic algorithms, for example to implement compile-time double dispatch.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I recently read about a neat trick regarding overloading of lambda expressions in C++ in a blog post by Dave Abrahams here. This technique was originally described by Mathias Gaunard. I want to do a short post about it here &hellip; <a href=\"http:\/\/martinecker.com\/martincodes\/lambda-expression-overloading\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_mi_skip_tracking":false,"footnotes":""},"categories":[10],"tags":[23,11,12],"class_list":["post-77","post","type-post","status-publish","format-standard","hentry","category-c","tag-c","tag-lambda-expressions","tag-tricks"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v19.12 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>C++11 Lambda Expression Overloading - Martin Codes<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"http:\/\/martinecker.com\/martincodes\/lambda-expression-overloading\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"C++11 Lambda Expression Overloading - Martin Codes\" \/>\n<meta property=\"og:description\" content=\"I recently read about a neat trick regarding overloading of lambda expressions in C++ in a blog post by Dave Abrahams here. This technique was originally described by Mathias Gaunard. I want to do a short post about it here &hellip; Continue reading &rarr;\" \/>\n<meta property=\"og:url\" content=\"http:\/\/martinecker.com\/martincodes\/lambda-expression-overloading\/\" \/>\n<meta property=\"og:site_name\" content=\"Martin Codes\" \/>\n<meta property=\"article:published_time\" content=\"2012-09-25T20:29:12+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2012-09-26T02:22:19+00:00\" \/>\n<meta name=\"author\" content=\"Martin Ecker\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Martin Ecker\" \/>\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\":\"WebPage\",\"@id\":\"http:\/\/martinecker.com\/martincodes\/lambda-expression-overloading\/\",\"url\":\"http:\/\/martinecker.com\/martincodes\/lambda-expression-overloading\/\",\"name\":\"C++11 Lambda Expression Overloading - Martin Codes\",\"isPartOf\":{\"@id\":\"http:\/\/martinecker.com\/martincodes\/#website\"},\"datePublished\":\"2012-09-25T20:29:12+00:00\",\"dateModified\":\"2012-09-26T02:22:19+00:00\",\"author\":{\"@id\":\"http:\/\/martinecker.com\/martincodes\/#\/schema\/person\/2ad254c988c5aaef13e54a1cadde5816\"},\"breadcrumb\":{\"@id\":\"http:\/\/martinecker.com\/martincodes\/lambda-expression-overloading\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"http:\/\/martinecker.com\/martincodes\/lambda-expression-overloading\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"http:\/\/martinecker.com\/martincodes\/lambda-expression-overloading\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"http:\/\/martinecker.com\/martincodes\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"C++11 Lambda Expression Overloading\"}]},{\"@type\":\"WebSite\",\"@id\":\"http:\/\/martinecker.com\/martincodes\/#website\",\"url\":\"http:\/\/martinecker.com\/martincodes\/\",\"name\":\"Martin Codes\",\"description\":\"Ramblings from a video game\/graphics programmer on anything coding- or graphics-related\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"http:\/\/martinecker.com\/martincodes\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"http:\/\/martinecker.com\/martincodes\/#\/schema\/person\/2ad254c988c5aaef13e54a1cadde5816\",\"name\":\"Martin Ecker\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"http:\/\/martinecker.com\/martincodes\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/7dfd53e699c35d22210a3c63e4b3e2cfae66f49029b0cde5f3c9d86847471d7a?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/7dfd53e699c35d22210a3c63e4b3e2cfae66f49029b0cde5f3c9d86847471d7a?s=96&d=mm&r=g\",\"caption\":\"Martin Ecker\"},\"url\":\"http:\/\/martinecker.com\/martincodes\/author\/admin\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"C++11 Lambda Expression Overloading - Martin Codes","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:\/\/martinecker.com\/martincodes\/lambda-expression-overloading\/","og_locale":"en_US","og_type":"article","og_title":"C++11 Lambda Expression Overloading - Martin Codes","og_description":"I recently read about a neat trick regarding overloading of lambda expressions in C++ in a blog post by Dave Abrahams here. This technique was originally described by Mathias Gaunard. I want to do a short post about it here &hellip; Continue reading &rarr;","og_url":"http:\/\/martinecker.com\/martincodes\/lambda-expression-overloading\/","og_site_name":"Martin Codes","article_published_time":"2012-09-25T20:29:12+00:00","article_modified_time":"2012-09-26T02:22:19+00:00","author":"Martin Ecker","twitter_misc":{"Written by":"Martin Ecker","Est. reading time":"2 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"http:\/\/martinecker.com\/martincodes\/lambda-expression-overloading\/","url":"http:\/\/martinecker.com\/martincodes\/lambda-expression-overloading\/","name":"C++11 Lambda Expression Overloading - Martin Codes","isPartOf":{"@id":"http:\/\/martinecker.com\/martincodes\/#website"},"datePublished":"2012-09-25T20:29:12+00:00","dateModified":"2012-09-26T02:22:19+00:00","author":{"@id":"http:\/\/martinecker.com\/martincodes\/#\/schema\/person\/2ad254c988c5aaef13e54a1cadde5816"},"breadcrumb":{"@id":"http:\/\/martinecker.com\/martincodes\/lambda-expression-overloading\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["http:\/\/martinecker.com\/martincodes\/lambda-expression-overloading\/"]}]},{"@type":"BreadcrumbList","@id":"http:\/\/martinecker.com\/martincodes\/lambda-expression-overloading\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"http:\/\/martinecker.com\/martincodes\/"},{"@type":"ListItem","position":2,"name":"C++11 Lambda Expression Overloading"}]},{"@type":"WebSite","@id":"http:\/\/martinecker.com\/martincodes\/#website","url":"http:\/\/martinecker.com\/martincodes\/","name":"Martin Codes","description":"Ramblings from a video game\/graphics programmer on anything coding- or graphics-related","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"http:\/\/martinecker.com\/martincodes\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"en-US"},{"@type":"Person","@id":"http:\/\/martinecker.com\/martincodes\/#\/schema\/person\/2ad254c988c5aaef13e54a1cadde5816","name":"Martin Ecker","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"http:\/\/martinecker.com\/martincodes\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/7dfd53e699c35d22210a3c63e4b3e2cfae66f49029b0cde5f3c9d86847471d7a?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/7dfd53e699c35d22210a3c63e4b3e2cfae66f49029b0cde5f3c9d86847471d7a?s=96&d=mm&r=g","caption":"Martin Ecker"},"url":"http:\/\/martinecker.com\/martincodes\/author\/admin\/"}]}},"_links":{"self":[{"href":"http:\/\/martinecker.com\/martincodes\/wp-json\/wp\/v2\/posts\/77","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/martinecker.com\/martincodes\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/martinecker.com\/martincodes\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/martinecker.com\/martincodes\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/martinecker.com\/martincodes\/wp-json\/wp\/v2\/comments?post=77"}],"version-history":[{"count":19,"href":"http:\/\/martinecker.com\/martincodes\/wp-json\/wp\/v2\/posts\/77\/revisions"}],"predecessor-version":[{"id":96,"href":"http:\/\/martinecker.com\/martincodes\/wp-json\/wp\/v2\/posts\/77\/revisions\/96"}],"wp:attachment":[{"href":"http:\/\/martinecker.com\/martincodes\/wp-json\/wp\/v2\/media?parent=77"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/martinecker.com\/martincodes\/wp-json\/wp\/v2\/categories?post=77"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/martinecker.com\/martincodes\/wp-json\/wp\/v2\/tags?post=77"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}