{"id":377,"date":"2021-01-15T22:52:13","date_gmt":"2021-01-15T21:52:13","guid":{"rendered":"https:\/\/janbielak.com\/?p=377"},"modified":"2023-03-28T12:55:49","modified_gmt":"2023-03-28T10:55:49","slug":"anonymous-types-in-c","status":"publish","type":"post","link":"https:\/\/janbielak.com\/index.php\/2021\/01\/15\/anonymous-types-in-c\/","title":{"rendered":"Anonymous types in C++"},"content":{"rendered":"\n<p>Since C++11 we have <em>lambdas <\/em>&#8211; anonymous functions that can be declared anywhere in code. They are quite a useful tool and have many additional capabilities when compared to regular functions. I am not going to talk about them here, as they are not the topic of this post, but one of them is especially useful &#8211; the ability for them to be defined in block scope, rather than only in namespace or class scope.<\/p>\n\n\n\n<p>A natural analogue to lambdas would be <em>anonymous types<\/em> that could be declared anywhere including inside expressions. You may say that since C++11 we already have such a tool &#8211; <code>std::tuple<\/code>s. However I wouldn&#8217;t call it an anonymous type, as it doesn&#8217;t have most of the properties that normal class types have:<\/p>\n\n\n\n<ul>\n<li>It can&#8217;t have methods<\/li>\n\n\n\n<li>It can&#8217;t have base classes<\/li>\n\n\n\n<li>It can&#8217;t have access specifiers &#8211; all &#8220;members&#8221; are &#8220;public&#8221;<\/li>\n\n\n\n<li>Its members can&#8217;t have names &#8211; instead they have to be accessed using the <s>ugly<\/s> verbose <code>std::get<\/code>.<\/li>\n\n\n\n<li>It can&#8217;t have static members<\/li>\n\n\n\n<li>It can&#8217;t model a union type &#8211; <code>std::optional<\/code>, <code>std::variant<\/code> and <code>std::any<\/code> are for that<\/li>\n\n\n\n<li>It can&#8217;t be templated<\/li>\n\n\n\n<li>It can&#8217;t have nested classes or enumerations<\/li>\n\n\n\n<li>It isn&#8217;t a unique type &#8211; <code>std::tuple&lt;const char*, int&gt;<\/code> is the same type regardless of whether it represents a person (name, age), an associative container key-value-pair or a span (memory block pointer, memory block size).<\/li>\n<\/ul>\n\n\n\n<p>The list could probably go on. You could say that tuples are not <em>meant<\/em> to be used like that and they don&#8217;t need all the capabilities that normal <code>struct<\/code>s and <code>class<\/code>es have, but the same argument could be used for lambdas, yet they have all functionality of normal functions (including templating them explicitly since C++20).<\/p>\n\n\n\n<p>When I think of anonymous types, I don&#8217;t want to have to deal with all these limitations. Wouldn&#8217;t it be great, if we could declare functions returning anonymous <code>struct<\/code>s with members that would have meaningful names that we could use to access them rather than by using <code>std::get<\/code>:<\/p>\n\n\n\n<pre style=\"background-color:#2b2b2b;color:#a9b7c6;font-family:'SF Mono','JetBrains Mono',monospace;font-size:9.8pt;\"><span style=\"color:#ed3792;\">struct&nbsp;<\/span><span style=\"color:#5a60c6;\">scroll_offset <\/span><span style=\"color:#6897bb;\">{ <\/span><span style=\"color:#ed3792;\">int <\/span><span style=\"color:#61c669;font-style:italic;\">width<\/span><span style=\"color:#af3681;\">, <\/span><span style=\"color:#61c669;font-style:italic;\">height<\/span><span style=\"color:#af3681;\">; <\/span><span style=\"color:#6897bb;\">} <\/span><span style=\"color:#ffc66d;font-weight:bold;\">getWindowSize<\/span><span style=\"color:#6989bb;\">(<\/span><span style=\"color:#5a60c6;\">GLFWwindow<\/span><span style=\"color:#af3681;\">* <\/span><span style=\"color:#54c665;font-style:italic;\">window<\/span><span style=\"color:#6989bb;\">) <\/span><span style=\"color:#6897bb;\">{\n<\/span><span style=\"color:#6897bb;\">    <\/span><span style=\"color:#ed3792;\">int <\/span><span style=\"color:#6dc68c;font-style:italic;\">width<\/span><span style=\"color:#af3681;\">, <\/span><span style=\"color:#6dc68c;font-style:italic;\">height<\/span><span style=\"color:#af3681;\">;\n<\/span><span style=\"color:#af3681;\">    <\/span><span style=\"color:#e0ff76;\">glfwGetWindowSize<\/span><span style=\"color:#6989bb;\">(<\/span><span style=\"color:#54c665;font-style:italic;\">window<\/span><span style=\"color:#af3681;\">, &amp;<\/span><span style=\"color:#6dc68c;font-style:italic;\">width<\/span><span style=\"color:#af3681;\">, &amp;<\/span><span style=\"color:#6dc68c;font-style:italic;\">height<\/span><span style=\"color:#6989bb;\">)<\/span><span style=\"color:#af3681;\">;\n<\/span><span style=\"color:#af3681;\">    <\/span><span style=\"color:#ed3792;\">return <\/span><span style=\"color:#6897bb;\">{<\/span><span style=\"color:#6dc68c;font-style:italic;\">width<\/span><span style=\"color:#af3681;\">, <\/span><span style=\"color:#6dc68c;font-style:italic;\">height<\/span><span style=\"color:#6897bb;\">}<\/span><span style=\"color:#af3681;\">;\n<\/span><span style=\"color:#6897bb;\">}<\/span><\/pre>\n\n\n\n<p>Or declare functions taking parameters of anonymous types that could be defined in place, in the function definition, without the need to pollute the enclosing scope:<\/p>\n\n\n\n<pre style=\"background-color:#2b2b2b;color:#a9b7c6;font-family:'SF Mono','JetBrains Mono',monospace;font-size:9.8pt;\"><span style=\"color:#ed3792;\">constexpr auto&nbsp;<\/span><span style=\"color:#ffc66d;font-weight:bold;\">simplify<\/span><span style=\"color:#6989bb;\">(<\/span><span style=\"color:#ed3792;\">struct&nbsp;<\/span><span style=\"color:#5a60c6;\"><\/span><span style=\"color:#6897bb;\">{<\/span><span style=\"color:#ed3792;\">int <\/span><span style=\"color:#61c669;font-style:italic;\">numerator<\/span><span style=\"color:#af3681;\">, <\/span><span style=\"color:#61c669;font-style:italic;\">denominator<\/span><span style=\"color:#af3681;\">;<\/span><span style=\"color:#6897bb;\">} <\/span><span style=\"color:#54c665;font-style:italic;\">ratio<\/span><span style=\"color:#6989bb;\">) <\/span><span style=\"color:#af3681;\">-&gt; <\/span><span style=\"color:#ed3792;\">decltype<\/span><span style=\"color:#6989bb;\">(<\/span><span style=\"color:#54c665;font-style:italic;\">ratio<\/span><span style=\"color:#6989bb;\">) <\/span><span style=\"color:#6897bb;\">{\n<\/span><span style=\"color:#6897bb;\">    <\/span><span style=\"color:#ed3792;\">int <\/span><span style=\"color:#6dc68c;font-style:italic;\">gcd <\/span><span style=\"color:#af3681;\">= <\/span><span style=\"color:#51bcff;\">std<\/span><span style=\"color:#af3681;\">::<\/span><span style=\"color:#e0ff76;\">gcd<\/span><span style=\"color:#6989bb;\">(<\/span><span style=\"color:#54c665;font-style:italic;\">ratio<\/span><span style=\"color:#af3681;\">.<\/span><span style=\"color:#61c669;font-style:italic;\">numerator<\/span><span style=\"color:#af3681;\">, <\/span><span style=\"color:#54c665;font-style:italic;\">ratio<\/span><span style=\"color:#af3681;\">.<\/span><span style=\"color:#61c669;font-style:italic;\">denominator<\/span><span style=\"color:#6989bb;\">)<\/span><span style=\"color:#af3681;\">;\n<\/span><span style=\"color:#af3681;\">    <\/span><span style=\"color:#ed3792;\">return <\/span><span style=\"color:#6897bb;\">{ <\/span><span style=\"color:#54c665;font-style:italic;\">ratio<\/span><span style=\"color:#af3681;\">.<\/span><span style=\"color:#61c669;font-style:italic;\">numerator <\/span><span style=\"color:#af3681;\">\/ <\/span><span style=\"color:#6dc68c;font-style:italic;\">gcd<\/span><span style=\"color:#af3681;\">, <\/span><span style=\"color:#54c665;font-style:italic;\">ratio<\/span><span style=\"color:#af3681;\">.<\/span><span style=\"color:#61c669;font-style:italic;\">denominator <\/span><span style=\"color:#af3681;\">\/ <\/span><span style=\"color:#6dc68c;font-style:italic;\">gcd <\/span><span style=\"color:#6897bb;\">}<\/span><span style=\"color:#af3681;\">;\n<\/span><span style=\"color:#6897bb;\">}<\/span><\/pre>\n\n\n\n<p>Or inherit from anonymous <code>class<\/code>es:<\/p>\n\n\n\n<pre style=\"background-color:#2b2b2b;color:#a9b7c6;font-family:'SF Mono','JetBrains Mono',monospace;font-size:9.8pt;\"><span style=\"color:#ed3792;\">class <\/span><span style=\"color:#5a60c6;\">Derived <\/span><span style=\"color:#af3681;\">:&nbsp;<\/span><span style=\"color:#ed3792;\">public&nbsp;<\/span><span style=\"color:#ed3792;\">class&nbsp;<\/span><span style=\"color:#5a60c6;\">Base <\/span><span style=\"color:#6897bb;\">{\n<\/span><span style=\"color:#6897bb;\">    <\/span><span style=\"color:#ed3792;\">int <\/span><span style=\"color:#61c669;font-style:italic;\">x<\/span><span style=\"color:#af3681;\">, <\/span><span style=\"color:#61c669;font-style:italic;\">y<\/span><span style=\"color:#af3681;\">;\n<\/span><span style=\"color:#ed3792;\">public<\/span><span style=\"color:#af3681;\">:\n<\/span><span style=\"color:#af3681;\">    <\/span><span style=\"color:#ed3792;\">int<\/span><span style=\"color:#af3681;\">&amp; <\/span><span style=\"color:#ffc66d;font-weight:bold;\">getX<\/span><span style=\"color:#6989bb;\">() <\/span><span style=\"color:#6897bb;\">{<\/span><span style=\"color:#ed3792;\">return <\/span><span style=\"color:#61c669;font-style:italic;\">x<\/span><span style=\"color:#af3681;\">; <\/span><span style=\"color:#6897bb;\">}\n<\/span><span style=\"color:#6897bb;\">    <\/span><span style=\"color:#ed3792;\">int<\/span><span style=\"color:#af3681;\">&amp; <\/span><span style=\"color:#ffc66d;font-weight:bold;\">getY<\/span><span style=\"color:#6989bb;\">() <\/span><span style=\"color:#6897bb;\">{<\/span><span style=\"color:#ed3792;\">return <\/span><span style=\"color:#61c669;font-style:italic;\">y<\/span><span style=\"color:#af3681;\">; <\/span><span style=\"color:#6897bb;\">}\n<\/span><span style=\"color:#6897bb;\">}<\/span>\n<span style=\"color:#6897bb;\">{\n<\/span><span style=\"color:#6897bb;\">    <\/span><span style=\"color:#ed3792;\">int <\/span><span style=\"color:#ffc66d;font-weight:bold;\">sum<\/span><span style=\"color:#6989bb;\">() <\/span><span style=\"color:#6897bb;\">{\n<\/span><span style=\"color:#6897bb;\">        <\/span><span style=\"color:#ed3792;\">return <\/span><span style=\"color:#e0ff76;\">getX<\/span><span style=\"color:#6989bb;\">() <\/span><span style=\"color:#af3681;\">+ <\/span><span style=\"color:#e0ff76;\">getY<\/span><span style=\"color:#6989bb;\">()<\/span><span style=\"color:#af3681;\">;\n<\/span><span style=\"color:#af3681;\">    <\/span><span style=\"color:#6897bb;\">}\n<\/span><span style=\"color:#6897bb;\">}<\/span><span style=\"color:#af3681;\">;<\/span><\/pre>\n\n\n\n<p>Sadly, its all just a dream&#8230; Or is it? What if I told you that you could code like that in C++ and compile it right now? Well, see for yourself (<a rel=\"noreferrer noopener\" href=\"https:\/\/godbolt.org\/z\/aEP634\" data-type=\"URL\" data-id=\"https:\/\/godbolt.org\/z\/aEP634\" target=\"_blank\">1<\/a>, <a rel=\"noreferrer noopener\" href=\"https:\/\/godbolt.org\/z\/xa6dfc\" data-type=\"URL\" data-id=\"https:\/\/godbolt.org\/z\/xa6dfc\" target=\"_blank\">2<\/a>, <a rel=\"noreferrer noopener\" href=\"https:\/\/godbolt.org\/z\/GMq3YP\" data-type=\"URL\" data-id=\"https:\/\/godbolt.org\/z\/GMq3YP\" target=\"_blank\">3<\/a>).<\/p>\n\n\n\n<p>Awesome, isn&#8217;t it? I&#8217;m sure there must be more use cases of anonymous types and this is just scratching the surface of what is possible in C++20. So how does this wizardry work, you may ask. Let&#8217;s dive into the code and see what&#8217;s inside.<\/p>\n\n\n\n<p><strong>Disclaimer:<\/strong> Before we start, I think its fair to say that the current compiler support for C++20 is minimal. The code below doesn&#8217;t compile on current Clang (11) at all and only certain use cases work on GCC (10) and MSVC (19.28). I expect issues to go away as time goes on and the compilers become more standard-compliant.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">C++20 &#8211; Brave New Code<\/h2>\n\n\n\n<p>Until C++20 there existed one particular forbidden usage of lambdas &#8211; declaration in <em>unevaluated contexts<\/em>. These include the expressions inside the <code>noexcept<\/code>, <code>typeid<\/code>, <code>sizeof<\/code> and probably the most importantly the <code>decltype<\/code> operators. Fortunately this has changed in C++20 for the better. The reasons for why the previous behaviour was limiting and how it was proposed to be changed can be found in <a rel=\"noreferrer noopener\" href=\"http:\/\/www.open-std.org\/jtc1\/sc22\/wg21\/docs\/papers\/2016\/p0315r1.pdf\" target=\"_blank\">P0315<\/a>.<\/p>\n\n\n\n<p>Another important change is that since <a rel=\"noreferrer noopener\" href=\"http:\/\/www.open-std.org\/jtc1\/sc22\/wg21\/docs\/papers\/2018\/p0732r2.pdf\" data-type=\"URL\" data-id=\"http:\/\/www.open-std.org\/jtc1\/sc22\/wg21\/docs\/papers\/2018\/p0732r2.pdf\" target=\"_blank\">P0732 <\/a>objects of certain class types can be <em>non-type template parameters<\/em> including <em>non-capturing lambdas<\/em>.<\/p>\n\n\n\n<p>This allows as to create a <code>lambda_holder<\/code> class that holds a lambda object as a part of its type and contains a <code>type<\/code> member type that holds the return type of the lambda:<\/p>\n\n\n\n<pre style=\"background-color:#2b2b2b;color:#a9b7c6;font-family:'SF Mono','JetBrains Mono',monospace;font-size:9.8pt;\"><span style=\"color:#ed3792;\">template <\/span><span style=\"color:#af3681;\">&lt;<\/span><span style=\"color:#ed3792;\">auto <\/span><span style=\"color:#0aa516;font-style:italic;\">LambdaObj<\/span><span style=\"color:#af3681;\">&gt;\n<\/span><span style=\"color:#ed3792;\">struct <\/span><span style=\"color:#5a60c6;\">lambda_holder\n<\/span><span style=\"color:#6897bb;\">{\n<\/span><span style=\"color:#6897bb;\">    <\/span><span style=\"color:#ed3792;\">using <\/span><span style=\"color:#836bc6;\">type <\/span><span style=\"color:#af3681;\">= <\/span><span style=\"color:#51bcff;\">std<\/span><span style=\"color:#af3681;\">::<\/span><span style=\"color:#836bc6;\">invoke_result_t<\/span><span style=\"color:#af3681;\">&lt;<\/span><span style=\"color:#ed3792;\">decltype<\/span><span style=\"color:#6989bb;\">(<\/span><span style=\"color:#0aa516;font-style:italic;\">LambdaObj<\/span><span style=\"color:#6989bb;\">)<\/span><span style=\"color:#af3681;\">&gt;;\n<\/span><span style=\"color:#6897bb;\">}<\/span><span style=\"color:#af3681;\">;\n<\/span><\/pre>\n\n\n\n<div class=\"wp-block-group\"><div class=\"wp-block-group__inner-container is-layout-flow wp-block-group-is-layout-flow\">\n<p>Actually this is the bare minimum of what is required to have anonymous types. At this point we already have a lot of functionality. In order to have anonymous types, the idea is to instantiate <code>lambda_holder<\/code> with a lambda object that returns an object of a type declared inside the lambda. Let&#8217;s see:<\/p>\n<\/div><\/div>\n\n\n\n<pre style=\"background-color:#2b2b2b;color:#a9b7c6;font-family:'SF Mono','JetBrains Mono',monospace;font-size:9.8pt;\"><span style=\"color:#ed3792;\">using <\/span><span style=\"color:#836bc6;\">anonymous_type <\/span><span style=\"color:#af3681;\">= <\/span><span style=\"color:#5a60c6;\">lambda_holder<\/span><span style=\"color:#af3681;\">&lt;<\/span>\n<span style=\"color:#af3681;\">&nbsp;   <\/span><span style=\"color:#af3681;\"><span style=\"color:#6db5bb;\">[]<\/span><span style=\"color:#6989bb;\">()<\/span><span style=\"color:#6897bb;\">{<\/span><\/span>\n<span style=\"color:#af3681;\"><span style=\"color:#6897bb;\">&nbsp;       <\/span><span style=\"color:#ed3792;\">struct&nbsp;<\/span><span style=\"color:#6897bb;\">{&nbsp;<\/span><span style=\"color:#ed3792;\">int&nbsp;<\/span><span style=\"color:#61c669;font-style:italic;\">x<\/span><span style=\"color:#af3681;\">,&nbsp;<\/span><span style=\"color:#61c669;font-style:italic;\">y<\/span><span style=\"color:#af3681;\">;&nbsp;<\/span><span style=\"color:#6897bb;\">}&nbsp;<\/span><span style=\"color:#6dc68c;font-style:italic;\">dummy<\/span><span style=\"color:#6897bb;\">{}<\/span><span style=\"color:#af3681;\">;<\/span><\/span>\n<span style=\"color:#af3681;\"><span style=\"color:#af3681;\">       &nbsp;<\/span><span style=\"color:#ed3792;\">return&nbsp;<\/span><span style=\"color:#6dc68c;font-style:italic;\">dummy<\/span><span style=\"color:#af3681;\">;&nbsp;<\/span><\/span>\n<span style=\"color:#af3681;\"><span style=\"color:#af3681;\">&nbsp;   <\/span><span style=\"color:#6897bb;\">}<\/span><\/span>\n<span style=\"color:#af3681;\">&gt;::<\/span><span style=\"color:#836bc6;\">type<\/span><span style=\"color:#af3681;\">;\n<\/span><\/pre>\n\n\n\n<p>Not particularly elegant, but it works. It has some issues that we have to solve (like what if the <code>struct<\/code> wouldn&#8217;t be <em>default-constructible<\/em>) and it lacks some functionality (like being able to declare an <em>anonymous template<\/em>), but it works. It is enough to work like in the examples (<a rel=\"noreferrer noopener\" href=\"https:\/\/godbolt.org\/z\/Y6cfdn\" data-type=\"URL\" data-id=\"https:\/\/godbolt.org\/z\/Y6cfdn\" target=\"_blank\">1<\/a>, <a rel=\"noreferrer noopener\" href=\"https:\/\/godbolt.org\/z\/M864xs\" data-type=\"URL\" data-id=\"https:\/\/godbolt.org\/z\/M864xs\" target=\"_blank\">2<\/a>, <a rel=\"noreferrer noopener\" href=\"https:\/\/godbolt.org\/z\/Gx5799\" data-type=\"URL\" data-id=\"https:\/\/godbolt.org\/z\/Gx5799\" target=\"_blank\">3<\/a>).<\/p>\n\n\n\n<p>What is different between this code and the code at the beginning of the article is that the former uses macros to make the anonymous type declaration less verbose and although it wasn&#8217;t shown in the examples it also allows to define anonymous templates and uses a bit of <em>template magic\u2122<\/em> to make it possible to omit writing <code>&lt;&gt;<\/code> when the type is not supposed to be a template.<\/p>\n\n\n\n<p>In this post I wanted to show off the idea of how anonymous types work and explaining fully how that implementation would be too long and out of scope, as this post is about the general idea. The interested reader can find the full implementation <a rel=\"noreferrer noopener\" href=\"https:\/\/github.com\/janekb04\/multifarious\/blob\/main\/include\/multifarious\/anonymous_type.h\" data-type=\"URL\" data-id=\"https:\/\/github.com\/janekb04\/multifarious\/blob\/main\/include\/multifarious\/anonymous_type.h\" target=\"_blank\">here<\/a>. The interface and implementation is thoroughly commented there. For now that library is only meant to be experimental and probably won&#8217;t be that useful until full support for C++20 arrives.<\/p>\n\n\n\n<p>I&#8217;m sure this idea can have a lot of different use cases that weren&#8217;t shown off here. The examples given were very basic and were only meant to show off what are some things that can be done, that couldn&#8217;t have been that like that before. Feel free to give your thoughts and comments down below. Very likely some mistakes have been made and I would be very thankful for any of them being reported. Thanks and I hope this idea will prove useful. <\/p>\n\n\n","protected":false},"excerpt":{"rendered":"<p>Since C++11 we have lambdas &#8211; anonymous functions that can be declared anywhere in code. They are quite a useful tool and have many additional capabilities when compared to regular functions. I am not going to talk about them here, as they are not the topic of this post, but one of them is especially [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":897,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[1],"tags":[23,15,20,16,24,19,25,18,17,22],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v22.7 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Anonymous types in C++ - Jan Bielak<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/janbielak.com\/index.php\/2021\/01\/15\/anonymous-types-in-c\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Anonymous types in C++ - Jan Bielak\" \/>\n<meta property=\"og:description\" content=\"Since C++11 we have lambdas &#8211; anonymous functions that can be declared anywhere in code. They are quite a useful tool and have many additional capabilities when compared to regular functions. I am not going to talk about them here, as they are not the topic of this post, but one of them is especially [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/janbielak.com\/index.php\/2021\/01\/15\/anonymous-types-in-c\/\" \/>\n<meta property=\"og:site_name\" content=\"Jan Bielak\" \/>\n<meta property=\"article:published_time\" content=\"2021-01-15T21:52:13+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2023-03-28T10:55:49+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/janbielak.com\/wp-content\/uploads\/2021\/01\/anon-thumb.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1170\" \/>\n\t<meta property=\"og:image:height\" content=\"1170\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Jan Bielak\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Jan Bielak\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"5 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/janbielak.com\/index.php\/2021\/01\/15\/anonymous-types-in-c\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/janbielak.com\/index.php\/2021\/01\/15\/anonymous-types-in-c\/\"},\"author\":{\"name\":\"Jan Bielak\",\"@id\":\"https:\/\/janbielak.com\/#\/schema\/person\/04eb61a91ea147e5ce8cc7d174ef800d\"},\"headline\":\"Anonymous types in C++\",\"datePublished\":\"2021-01-15T21:52:13+00:00\",\"dateModified\":\"2023-03-28T10:55:49+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/janbielak.com\/index.php\/2021\/01\/15\/anonymous-types-in-c\/\"},\"wordCount\":957,\"publisher\":{\"@id\":\"https:\/\/janbielak.com\/#\/schema\/person\/04eb61a91ea147e5ce8cc7d174ef800d\"},\"image\":{\"@id\":\"https:\/\/janbielak.com\/index.php\/2021\/01\/15\/anonymous-types-in-c\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/i0.wp.com\/janbielak.com\/wp-content\/uploads\/2021\/01\/anon-thumb.png?fit=1170%2C1170&ssl=1\",\"keywords\":[\"anonymous\",\"c++\",\"c++20\",\"cpp\",\"expressive\",\"lambda\",\"metaprogramming\",\"programming\",\"template\",\"type\"],\"inLanguage\":\"en\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/janbielak.com\/index.php\/2021\/01\/15\/anonymous-types-in-c\/\",\"url\":\"https:\/\/janbielak.com\/index.php\/2021\/01\/15\/anonymous-types-in-c\/\",\"name\":\"Anonymous types in C++ - Jan Bielak\",\"isPartOf\":{\"@id\":\"https:\/\/janbielak.com\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/janbielak.com\/index.php\/2021\/01\/15\/anonymous-types-in-c\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/janbielak.com\/index.php\/2021\/01\/15\/anonymous-types-in-c\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/i0.wp.com\/janbielak.com\/wp-content\/uploads\/2021\/01\/anon-thumb.png?fit=1170%2C1170&ssl=1\",\"datePublished\":\"2021-01-15T21:52:13+00:00\",\"dateModified\":\"2023-03-28T10:55:49+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/janbielak.com\/index.php\/2021\/01\/15\/anonymous-types-in-c\/#breadcrumb\"},\"inLanguage\":\"en\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/janbielak.com\/index.php\/2021\/01\/15\/anonymous-types-in-c\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en\",\"@id\":\"https:\/\/janbielak.com\/index.php\/2021\/01\/15\/anonymous-types-in-c\/#primaryimage\",\"url\":\"https:\/\/i0.wp.com\/janbielak.com\/wp-content\/uploads\/2021\/01\/anon-thumb.png?fit=1170%2C1170&ssl=1\",\"contentUrl\":\"https:\/\/i0.wp.com\/janbielak.com\/wp-content\/uploads\/2021\/01\/anon-thumb.png?fit=1170%2C1170&ssl=1\",\"width\":1170,\"height\":1170},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/janbielak.com\/index.php\/2021\/01\/15\/anonymous-types-in-c\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/janbielak.com\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Anonymous types in C++\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/janbielak.com\/#website\",\"url\":\"https:\/\/janbielak.com\/\",\"name\":\"Jan Bielak\",\"description\":\"C++ Programming and Computer Graphics...\",\"publisher\":{\"@id\":\"https:\/\/janbielak.com\/#\/schema\/person\/04eb61a91ea147e5ce8cc7d174ef800d\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/janbielak.com\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\/\/janbielak.com\/#\/schema\/person\/04eb61a91ea147e5ce8cc7d174ef800d\",\"name\":\"Jan Bielak\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en\",\"@id\":\"https:\/\/janbielak.com\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/0724454f30bc6b720ca31ca3286eba20?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/0724454f30bc6b720ca31ca3286eba20?s=96&d=mm&r=g\",\"caption\":\"Jan Bielak\"},\"logo\":{\"@id\":\"https:\/\/janbielak.com\/#\/schema\/person\/image\/\"},\"sameAs\":[\"https:\/\/janbielak.com\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Anonymous types in C++ - Jan Bielak","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":"https:\/\/janbielak.com\/index.php\/2021\/01\/15\/anonymous-types-in-c\/","og_locale":"en_US","og_type":"article","og_title":"Anonymous types in C++ - Jan Bielak","og_description":"Since C++11 we have lambdas &#8211; anonymous functions that can be declared anywhere in code. They are quite a useful tool and have many additional capabilities when compared to regular functions. I am not going to talk about them here, as they are not the topic of this post, but one of them is especially [&hellip;]","og_url":"https:\/\/janbielak.com\/index.php\/2021\/01\/15\/anonymous-types-in-c\/","og_site_name":"Jan Bielak","article_published_time":"2021-01-15T21:52:13+00:00","article_modified_time":"2023-03-28T10:55:49+00:00","og_image":[{"width":1170,"height":1170,"url":"https:\/\/janbielak.com\/wp-content\/uploads\/2021\/01\/anon-thumb.png","type":"image\/png"}],"author":"Jan Bielak","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Jan Bielak","Est. reading time":"5 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/janbielak.com\/index.php\/2021\/01\/15\/anonymous-types-in-c\/#article","isPartOf":{"@id":"https:\/\/janbielak.com\/index.php\/2021\/01\/15\/anonymous-types-in-c\/"},"author":{"name":"Jan Bielak","@id":"https:\/\/janbielak.com\/#\/schema\/person\/04eb61a91ea147e5ce8cc7d174ef800d"},"headline":"Anonymous types in C++","datePublished":"2021-01-15T21:52:13+00:00","dateModified":"2023-03-28T10:55:49+00:00","mainEntityOfPage":{"@id":"https:\/\/janbielak.com\/index.php\/2021\/01\/15\/anonymous-types-in-c\/"},"wordCount":957,"publisher":{"@id":"https:\/\/janbielak.com\/#\/schema\/person\/04eb61a91ea147e5ce8cc7d174ef800d"},"image":{"@id":"https:\/\/janbielak.com\/index.php\/2021\/01\/15\/anonymous-types-in-c\/#primaryimage"},"thumbnailUrl":"https:\/\/i0.wp.com\/janbielak.com\/wp-content\/uploads\/2021\/01\/anon-thumb.png?fit=1170%2C1170&ssl=1","keywords":["anonymous","c++","c++20","cpp","expressive","lambda","metaprogramming","programming","template","type"],"inLanguage":"en"},{"@type":"WebPage","@id":"https:\/\/janbielak.com\/index.php\/2021\/01\/15\/anonymous-types-in-c\/","url":"https:\/\/janbielak.com\/index.php\/2021\/01\/15\/anonymous-types-in-c\/","name":"Anonymous types in C++ - Jan Bielak","isPartOf":{"@id":"https:\/\/janbielak.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/janbielak.com\/index.php\/2021\/01\/15\/anonymous-types-in-c\/#primaryimage"},"image":{"@id":"https:\/\/janbielak.com\/index.php\/2021\/01\/15\/anonymous-types-in-c\/#primaryimage"},"thumbnailUrl":"https:\/\/i0.wp.com\/janbielak.com\/wp-content\/uploads\/2021\/01\/anon-thumb.png?fit=1170%2C1170&ssl=1","datePublished":"2021-01-15T21:52:13+00:00","dateModified":"2023-03-28T10:55:49+00:00","breadcrumb":{"@id":"https:\/\/janbielak.com\/index.php\/2021\/01\/15\/anonymous-types-in-c\/#breadcrumb"},"inLanguage":"en","potentialAction":[{"@type":"ReadAction","target":["https:\/\/janbielak.com\/index.php\/2021\/01\/15\/anonymous-types-in-c\/"]}]},{"@type":"ImageObject","inLanguage":"en","@id":"https:\/\/janbielak.com\/index.php\/2021\/01\/15\/anonymous-types-in-c\/#primaryimage","url":"https:\/\/i0.wp.com\/janbielak.com\/wp-content\/uploads\/2021\/01\/anon-thumb.png?fit=1170%2C1170&ssl=1","contentUrl":"https:\/\/i0.wp.com\/janbielak.com\/wp-content\/uploads\/2021\/01\/anon-thumb.png?fit=1170%2C1170&ssl=1","width":1170,"height":1170},{"@type":"BreadcrumbList","@id":"https:\/\/janbielak.com\/index.php\/2021\/01\/15\/anonymous-types-in-c\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/janbielak.com\/"},{"@type":"ListItem","position":2,"name":"Anonymous types in C++"}]},{"@type":"WebSite","@id":"https:\/\/janbielak.com\/#website","url":"https:\/\/janbielak.com\/","name":"Jan Bielak","description":"C++ Programming and Computer Graphics...","publisher":{"@id":"https:\/\/janbielak.com\/#\/schema\/person\/04eb61a91ea147e5ce8cc7d174ef800d"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/janbielak.com\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"en"},{"@type":["Person","Organization"],"@id":"https:\/\/janbielak.com\/#\/schema\/person\/04eb61a91ea147e5ce8cc7d174ef800d","name":"Jan Bielak","image":{"@type":"ImageObject","inLanguage":"en","@id":"https:\/\/janbielak.com\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/0724454f30bc6b720ca31ca3286eba20?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/0724454f30bc6b720ca31ca3286eba20?s=96&d=mm&r=g","caption":"Jan Bielak"},"logo":{"@id":"https:\/\/janbielak.com\/#\/schema\/person\/image\/"},"sameAs":["https:\/\/janbielak.com"]}]}},"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"https:\/\/i0.wp.com\/janbielak.com\/wp-content\/uploads\/2021\/01\/anon-thumb.png?fit=1170%2C1170&ssl=1","jetpack-related-posts":[],"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/janbielak.com\/index.php\/wp-json\/wp\/v2\/posts\/377"}],"collection":[{"href":"https:\/\/janbielak.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/janbielak.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/janbielak.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/janbielak.com\/index.php\/wp-json\/wp\/v2\/comments?post=377"}],"version-history":[{"count":37,"href":"https:\/\/janbielak.com\/index.php\/wp-json\/wp\/v2\/posts\/377\/revisions"}],"predecessor-version":[{"id":898,"href":"https:\/\/janbielak.com\/index.php\/wp-json\/wp\/v2\/posts\/377\/revisions\/898"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/janbielak.com\/index.php\/wp-json\/wp\/v2\/media\/897"}],"wp:attachment":[{"href":"https:\/\/janbielak.com\/index.php\/wp-json\/wp\/v2\/media?parent=377"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/janbielak.com\/index.php\/wp-json\/wp\/v2\/categories?post=377"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/janbielak.com\/index.php\/wp-json\/wp\/v2\/tags?post=377"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}