{"id":1868,"date":"2026-09-03T08:39:05","date_gmt":"2026-09-03T14:39:05","guid":{"rendered":"https:\/\/www.elbeno.com\/blog\/?p=1868"},"modified":"2026-09-03T08:39:05","modified_gmt":"2026-09-03T14:39:05","slug":"partial-application-of-class-templates","status":"publish","type":"post","link":"https:\/\/www.elbeno.com\/blog\/?p=1868","title":{"rendered":"Partial application of class templates"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">A class template is a function from type(s) to type. So it makes sense that we would be able to partially apply that function.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This is a major use case: looking at an industry-standard metaprogramming library like Boost.mp11, it&#8217;s littered with duplication of algorithms in two forms: one taking a regular (meta-)function and another with a <code>_q<\/code> suffix taking a quoted metafunction. The documentation doesn&#8217;t really explain when you would want to use a quoted metafunction, but if you do much metaprogramming, you run into it pretty quickly. It&#8217;s one way we bind arguments for partial application:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>template &lt;typename T>\nstruct my_func {\n  template &lt;typename U>\n  using fn = \/* some function of T and U *\/;\n};\n\n\/\/ we bind T so that the iteration works on a function of one argument (U)\nusing new_type_list = mp_transform_q&lt;my_func&lt;int>, old_type_list>;<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">And in fact Boost.mp11 also has <code>mp_bind<\/code> and friends to do this kind of partial application:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>template &lt;typename T, typename U>\nusing my_func = \/* some function of T and U *\/;\n\nusing new_type_list = mp_transform_q&lt;mp_bind&lt;my_func, int>, old_type_list>;<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">But <code>mp_bind<\/code> still produces a quoted metafunction, so we still need the <code>_q<\/code> algorithms. If we had this kind of partial application more &#8220;built-in&#8221;, we could perhaps get rid of (most of? all of?) those quoted metafunctions and the algorithm duplication.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Reflection gives us a pretty straightforward way to achieve this. Partial application like this is basically a better <code>substitute<\/code>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/godbolt.org\/z\/nobr6cMrd\">https:\/\/godbolt.org\/z\/nobr6cMrd<\/a><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">(It would be even better if <code>substitute<\/code> had built-in partial application that would produce a new template&#8230; we can but dream&#8230;)<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If you like, you can think of this as equivalent to giving up &#8220;natural&#8221; function call syntax <code>f(1, 2, 3)<\/code> and using instead <code>invoke(f, 1, 2, 3)<\/code> so that we can treat all kinds of &#8220;functions&#8221; generically. And we could do the same sort of thing with <code>mp_bind<\/code> today, at the complexity cost of making everything a quoted metafunction. Reflection just allows us to hide that away better?<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">I also know the cool kids these days want to do everything with reflection and <code>consteval<\/code> programming rather than slinging types around, but there are plenty of folks who still like type-based metaprogramming and the functional style it brings. At the moment, many type-based (and especially alias-based) approaches might also be faster than leaning on <code>consteval<\/code> evaluations. Maybe we can mix a little reflection in to improve the type-based approach sometimes.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">It&#8217;s entirely likely that we can go further, and metaprogramming may change much more. And yes this is only one aspect of metaprogramming, dealing with classes only, etc. But this is one step down the progress path perhaps. I wonder what an industry-standard MP library will look like in 10 years&#8217; time.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n","protected":false},"excerpt":{"rendered":"<p>A class template is a function from type(s) to type. So it makes sense that we would be able to partially apply that function. This is a major use case: looking at an industry-standard metaprogramming library like Boost.mp11, it&#8217;s littered with duplication of algorithms in two forms: one taking a&#8230;<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[22],"tags":[],"class_list":["post-1868","post","type-post","status-publish","format-standard","hentry","category-cpp"],"_links":{"self":[{"href":"https:\/\/www.elbeno.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/1868","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.elbeno.com\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.elbeno.com\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.elbeno.com\/blog\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.elbeno.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1868"}],"version-history":[{"count":1,"href":"https:\/\/www.elbeno.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/1868\/revisions"}],"predecessor-version":[{"id":1869,"href":"https:\/\/www.elbeno.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/1868\/revisions\/1869"}],"wp:attachment":[{"href":"https:\/\/www.elbeno.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1868"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.elbeno.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1868"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.elbeno.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1868"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}