{"id":4389,"date":"2021-12-23T12:17:28","date_gmt":"2021-12-23T10:17:28","guid":{"rendered":"https:\/\/mariusbancila.ro\/blog\/?p=4389"},"modified":"2021-12-23T22:35:31","modified_gmt":"2021-12-23T20:35:31","slug":"use-cases-of-variable-templates-in-cpp","status":"publish","type":"post","link":"https:\/\/mariusbancila.ro\/blog\/2021\/12\/23\/use-cases-of-variable-templates-in-cpp\/","title":{"rendered":"Use Cases of Variable Templates in C++"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Since C++14 variables can also be templatized. A variable template defines a family of variable (when declared at namespace scope) or a family of static data members (when defined at class scope). The question is, what is the benefit of variable templates?<\/p>\n\n\n\n<!--more-->\n\n\n\n<p class=\"wp-block-paragraph\">I have seen the example of defining PI as a variable template quite often. Here it is from <a href=\"https:\/\/en.cppreference.com\/w\/cpp\/language\/variable_template\" target=\"_blank\" rel=\"noreferrer noopener\">cppreference<\/a>:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">template&lt;class T>\nconstexpr T pi = T(3.1415926535897932385L);  \/\/ variable template\n \ntemplate&lt;class T>\nT circular_area(T r)                         \/\/ function template\n{\n    return pi&lt;T> * r * r;                    \/\/ pi&lt;T> is a variable template instantiation\n}<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This is not necessarily a bad example but I think more complex examples would be helpful to better understand the use of variable templates. I&#8217;ll try to share such examples here. <\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Use case: reducing code<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The <a href=\"https:\/\/github.com\/mariusbancila\/stduuid\" target=\"_blank\" rel=\"noreferrer noopener\">stduuid library<\/a> provides a cross-platform implementation for universally unique identifiers (uuids or guids). It features a function called <code>to_string()<\/code> that returns a string representation of a uuid, such as <code>\"47183823-2574-4bfd-b411-99ed177d3e43\"<\/code>. Recently, I have optimized the implementation of this function for speed. At the first attempt, this function looked as follows:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">template&lt;class CharT = char,\n         class Traits = std::char_traits&lt;CharT>,\n         class Allocator = std::allocator&lt;CharT>>\ninline std::basic_string&lt;CharT, Traits, Allocator> to_string(uuid const&amp; id)\n{\n   CharT uustr[] = \"00000000-0000-0000-0000-000000000000\";\n   constexpr CharT encode[] = \"0123456789abcdef\";\n\n   for (size_t i = 0, index = 0; i &lt; 36; ++i)\n   {\n      if (i == 8 || i == 13 || i == 18 || i == 23)\n      {\n         continue;\n      }\n      uustr[i] = encode[id.data[index] >> 4 &amp; 0x0f];\n      uustr[++i] = encode[id.data[index] &amp; 0x0f];\n      index++;\n   }\n\n   return uustr;\n}<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">You can create a uuid from a string and then convert back to string as follows:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">auto guid = uuids::uuid::from_string(\"47183823-2574-4bfd-b411-99ed177d3e43\").value();\nREQUIRE(uuids::to_string(guid) == \"47183823-2574-4bfd-b411-99ed177d3e43\");<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This works fine, but if you try to convert to a string of wide characters, then it no longer works:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">auto guid = uuids::uuid::from_string(\"47183823-2574-4bfd-b411-99ed177d3e43\").value();\nREQUIRE(uuids::to_string&lt;wchar_t>(guid) == L\"47183823-2574-4bfd-b411-99ed177d3e43\");<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This snippet produces the following errors in VC++:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">1>test_uuid.cpp\n1>uuid.h(614,1): error C2440: 'initializing': cannot convert from 'const char [37]' to 'CharT []'\n1>        with\n1>        [\n1>            CharT=wchar_t\n1>        ]\n1>uuid.h(614,21): message : The type of the string literal is not compatible with the type of the array\n1>test_uuid.cpp(191): message : see reference to function template instantiation 'std::basic_string&lt;wchar_t,std::char_traits&lt;wchar_t>,std::allocator&lt;wchar_t>> uuids::to_string&lt;wchar_t,std::char_traits&lt;wchar_t>,std::allocator&lt;wchar_t>>(const uuids::uuid &amp;)' being compiled\n1>uuid.h(615,1): error C2440: 'initializing': cannot convert from 'const char [17]' to 'const CharT []'\n1>        with\n1>        [\n1>            CharT=wchar_t\n1>        ]\n1>uuid.h(615,32): message : The type of the string literal is not compatible with the type of the array\n1>uuid.h(615,32): error C2131: expression did not evaluate to a constant\n1>uuid.h(615,32): message : a non-constant (sub-)expression was encountered\n<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">A possible solution to fix this problem is to specialize <code>to_string()<\/code> for <code>wchar_t<\/code>. This can be done as follows:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">template&lt;>\ninline std::wstring to_string(uuid const&amp; id)\n{\n   wchar_t uustr[] = L\"00000000-0000-0000-0000-000000000000\";\n   constexpr wchar_t encode[] = L\"0123456789abcdef\";\n\n   for (size_t i = 0, index = 0; i &lt; 36; ++i)\n   {\n      if (i == 8 || i == 13 || i == 18 || i == 23)\n      {\n         continue;\n      }\n      uustr[i] = encode[id.data[index] >> 4 &amp; 0x0f];\n      uustr[++i] = encode[id.data[index] &amp; 0x0f];\n      index++;\n   }\n\n   return std::wstring(uustr);\n}<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This works fine, the compiler errors are gone and the program runs as expected. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">However, we now have identical duplicate code. The only difference is the initialization of the <code>uustr<\/code> and <code>encode<\/code> arrays. This kinda defeats the purpose of template to avoid repetitive code. We can fix this, with the help of variable templates. Here is how:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">First, we will define two variable templates as follows:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">namespace detail\n{\n   template &lt;typename CharT>\n   constexpr CharT empty_guid[37] = \"00000000-0000-0000-0000-000000000000\";\n\n   template &lt;typename CharT>\n   constexpr CharT guid_encoder[17] = \"0123456789abcdef\";\n}<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">We will need to specialize them for the <code>wchar_t<\/code> type so that we can initialize them with wide string literals. This is also done in the <code>detail<\/code> namespace (not shown below):<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">template &lt;>\nconstexpr wchar_t empty_guid&lt;wchar_t>[37] = L\"00000000-0000-0000-0000-000000000000\";\n\ntemplate &lt;>\nconstexpr wchar_t guid_encoder&lt;wchar_t>[17] = L\"0123456789abcdef\";<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Having these, we can change the implementation of the <code>to_string()<\/code> function template as follows:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">template&lt;class CharT = char,\n         class Traits = std::char_traits&lt;CharT>,\n         class Allocator = std::allocator&lt;CharT>>\ninline std::basic_string&lt;CharT, Traits, Allocator> to_string(uuid const &amp; id)\n{\n   std::basic_string&lt;CharT, Traits, Allocator> uustr{detail::empty_guid&lt;CharT>};\n\n   for (size_t i = 0, index = 0; i &lt; 36; ++i)\n   {\n      if (i == 8 || i == 13 || i == 18 || i == 23)\n      {\n         continue;\n      }\n      uustr[i] = detail::guid_encoder&lt;CharT>[id.data[index] >> 4 &amp; 0x0f];\n      uustr[++i] = detail::guid_encoder&lt;CharT>[id.data[index] &amp; 0x0f];\n      index++;\n   }\n\n   return uustr;\n}<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">We only have a primary template, there is no need for the explicit full specialization for <code>wchar_t<\/code>. We do have that for the variable templates, so there is some duplicate code, but the implementation of <code>to_string()<\/code> (which contains much more code) is no longer duplicated.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Use case: improve readability<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Apart from this, there is also the use case of simplifying the code when using type traits. Type traits that help us query properties of types provide a data member Boolean called <code>value<\/code>, which is initialized to <code>true<\/code> or <code>false<\/code> depending on the property of a type. Here is an example:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">template &lt;typename T>\nstruct is_floating_point\n{\n   static constexpr bool value = false;\n};\n\ntemplate &lt;>\nstruct is_floating_point&lt;float>\n{\n   static constexpr bool value = true;\n};\n\ntemplate &lt;>\nstruct is_floating_point&lt;double>\n{\n   static constexpr bool value = true;\n};\n\ntemplate &lt;>\nstruct is_floating_point&lt;long double>\n{\n   static constexpr bool value = true;\n};<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">There is a primary template and three specializations for <code>float<\/code>, <code>double<\/code>, and <code>long doble<\/code>. We can use this type trait to constrain the template arguments of a function as follows:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">template &lt;typename T>\nrequires is_floating_point&lt;T>::value\nauto add(T a, T b)\n{\n   return a + b;\n}<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">However, this requires the use of the verbose <code>::value<\/code> which can lead to hard to read code in many cases. This is where a variable template can help improve readability. We can define one as follows:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">template &lt;typename T>\nconstexpr bool is_floating_point_v = is_floating_point&lt;T>::value;<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">And we can use it as shown below:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">template &lt;typename T>\nrequires is_floating_point_v&lt;T>\nauto add(T a, T b)\n{\n   return a + b;\n}<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Starting with C++17, the standard defines variable templates like this for all the type traits from the standard library. There is, of course, a <code>std::is_floating_point<\/code> class template, and a <code>std::is_floating_point_v<\/code> variable template.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Conclusion<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">In conclusion, variable templates are an important feature in the language to help us reduce template code and improve their readability.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If you have other good examples for using variable templates please share them in the comments.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Since C++14 variables can also be templatized. A variable template defines a family of variable (when declared at namespace scope) or a family of static data members (when defined at class scope). The question is, what is the benefit of variable templates?<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_uag_custom_page_level_css":"","advgb_blocks_editor_width":"","advgb_blocks_columns_visual_guide":"","_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_feature_clip_id":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2},"jetpack_post_was_ever_published":false},"categories":[7],"tags":[451,513,475,323],"class_list":["post-4389","post","type-post","status-publish","format-standard","hentry","category-c","tag-c","tag-c14","tag-c17","tag-templates"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.3 - aioseo.com -->\n\t<meta name=\"description\" content=\"Learn about variable templates in C++ and how they help reduce template code and improve readability.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Marius Bancila\"\/>\n\t<meta name=\"keywords\" content=\"c++,c++14,c++17,templates\" \/>\n\t<link rel=\"canonical\" href=\"https:\/\/mariusbancila.ro\/blog\/2021\/12\/23\/use-cases-of-variable-templates-in-cpp\/\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.3\" \/>\n\t\t<meta property=\"og:locale\" content=\"en_US\" \/>\n\t\t<meta property=\"og:site_name\" content=\"Marius Bancila&#039;s Blog | About code. Mostly on C++\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"Use Cases of Variable Templates in C++\" \/>\n\t\t<meta property=\"og:description\" content=\"Learn about variable templates in C++ and how they help reduce template code and improve readability.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/mariusbancila.ro\/blog\/2021\/12\/23\/use-cases-of-variable-templates-in-cpp\/\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2021-12-23T10:17:28+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2021-12-23T20:35:31+00:00\" \/>\n\t\t<meta name=\"twitter:card\" content=\"summary\" \/>\n\t\t<meta name=\"twitter:title\" content=\"Use Cases of Variable Templates in C++\" \/>\n\t\t<meta name=\"twitter:description\" content=\"Learn about variable templates in C++ and how they help reduce template code and improve readability.\" \/>\n\t\t<script type=\"application\/ld+json\" class=\"aioseo-schema\">\n\t\t\t{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2021\\\/12\\\/23\\\/use-cases-of-variable-templates-in-cpp\\\/#article\",\"name\":\"Use Cases of Variable Templates in C++\",\"headline\":\"Use Cases of Variable Templates in C++\",\"author\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/author\\\/admin\\\/#author\"},\"publisher\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/#organization\"},\"datePublished\":\"2021-12-23T12:17:28+02:00\",\"dateModified\":\"2021-12-23T22:35:31+02:00\",\"inLanguage\":\"en-US\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2021\\\/12\\\/23\\\/use-cases-of-variable-templates-in-cpp\\\/#webpage\"},\"isPartOf\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2021\\\/12\\\/23\\\/use-cases-of-variable-templates-in-cpp\\\/#webpage\"},\"articleSection\":\"C++, C++, C++14, C++17, templates\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2021\\\/12\\\/23\\\/use-cases-of-variable-templates-in-cpp\\\/#breadcrumblist\",\"itemListElement\":[{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/#listItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/#listItem\",\"name\":\"IT\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/#listItem\",\"position\":2,\"name\":\"IT\",\"item\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/#listItem\",\"name\":\"Software\"},\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/#listItem\",\"name\":\"Home\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/#listItem\",\"position\":3,\"name\":\"Software\",\"item\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/c\\\/#listItem\",\"name\":\"C++\"},\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/#listItem\",\"name\":\"IT\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/c\\\/#listItem\",\"position\":4,\"name\":\"C++\",\"item\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/c\\\/\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2021\\\/12\\\/23\\\/use-cases-of-variable-templates-in-cpp\\\/#listItem\",\"name\":\"Use Cases of Variable Templates in C++\"},\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/#listItem\",\"name\":\"Software\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2021\\\/12\\\/23\\\/use-cases-of-variable-templates-in-cpp\\\/#listItem\",\"position\":5,\"name\":\"Use Cases of Variable Templates in C++\",\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/c\\\/#listItem\",\"name\":\"C++\"}}]},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/#organization\",\"name\":\"Marius Bancila's Blog\",\"description\":\"About code. Mostly on C++\",\"url\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/author\\\/admin\\\/#author\",\"url\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/author\\\/admin\\\/\",\"name\":\"Marius Bancila\",\"image\":{\"@type\":\"ImageObject\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2021\\\/12\\\/23\\\/use-cases-of-variable-templates-in-cpp\\\/#authorImage\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/a84dd2831d955c38355ddea55df4df260809b88f36408bc14fd4eab8f7f131c9?s=96&d=mm&r=g\",\"width\":96,\"height\":96,\"caption\":\"Marius Bancila\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2021\\\/12\\\/23\\\/use-cases-of-variable-templates-in-cpp\\\/#webpage\",\"url\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2021\\\/12\\\/23\\\/use-cases-of-variable-templates-in-cpp\\\/\",\"name\":\"Use Cases of Variable Templates in C++\",\"description\":\"Learn about variable templates in C++ and how they help reduce template code and improve readability.\",\"inLanguage\":\"en-US\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/#website\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2021\\\/12\\\/23\\\/use-cases-of-variable-templates-in-cpp\\\/#breadcrumblist\"},\"author\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/author\\\/admin\\\/#author\"},\"creator\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/author\\\/admin\\\/#author\"},\"datePublished\":\"2021-12-23T12:17:28+02:00\",\"dateModified\":\"2021-12-23T22:35:31+02:00\"},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/\",\"name\":\"Marius Bancila's Blog\",\"description\":\"About code. Mostly on C++\",\"inLanguage\":\"en-US\",\"publisher\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/#organization\"}}]}\n\t\t<\/script>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"Use Cases of Variable Templates in C++","description":"Learn about variable templates in C++ and how they help reduce template code and improve readability.","canonical_url":"https:\/\/mariusbancila.ro\/blog\/2021\/12\/23\/use-cases-of-variable-templates-in-cpp\/","robots":"max-image-preview:large","keywords":"c++,c++14,c++17,templates","webmasterTools":{"miscellaneous":""},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/mariusbancila.ro\/blog\/2021\/12\/23\/use-cases-of-variable-templates-in-cpp\/#article","name":"Use Cases of Variable Templates in C++","headline":"Use Cases of Variable Templates in C++","author":{"@id":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/#author"},"publisher":{"@id":"https:\/\/mariusbancila.ro\/blog\/#organization"},"datePublished":"2021-12-23T12:17:28+02:00","dateModified":"2021-12-23T22:35:31+02:00","inLanguage":"en-US","mainEntityOfPage":{"@id":"https:\/\/mariusbancila.ro\/blog\/2021\/12\/23\/use-cases-of-variable-templates-in-cpp\/#webpage"},"isPartOf":{"@id":"https:\/\/mariusbancila.ro\/blog\/2021\/12\/23\/use-cases-of-variable-templates-in-cpp\/#webpage"},"articleSection":"C++, C++, C++14, C++17, templates"},{"@type":"BreadcrumbList","@id":"https:\/\/mariusbancila.ro\/blog\/2021\/12\/23\/use-cases-of-variable-templates-in-cpp\/#breadcrumblist","itemListElement":[{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/#listItem","position":1,"name":"Home","item":"https:\/\/mariusbancila.ro\/blog\/","nextItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/#listItem","name":"IT"}},{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/#listItem","position":2,"name":"IT","item":"https:\/\/mariusbancila.ro\/blog\/category\/it\/","nextItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/#listItem","name":"Software"},"previousItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/#listItem","name":"Home"}},{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/#listItem","position":3,"name":"Software","item":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/","nextItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/c\/#listItem","name":"C++"},"previousItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/#listItem","name":"IT"}},{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/c\/#listItem","position":4,"name":"C++","item":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/c\/","nextItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/2021\/12\/23\/use-cases-of-variable-templates-in-cpp\/#listItem","name":"Use Cases of Variable Templates in C++"},"previousItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/#listItem","name":"Software"}},{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/2021\/12\/23\/use-cases-of-variable-templates-in-cpp\/#listItem","position":5,"name":"Use Cases of Variable Templates in C++","previousItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/c\/#listItem","name":"C++"}}]},{"@type":"Organization","@id":"https:\/\/mariusbancila.ro\/blog\/#organization","name":"Marius Bancila's Blog","description":"About code. Mostly on C++","url":"https:\/\/mariusbancila.ro\/blog\/"},{"@type":"Person","@id":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/#author","url":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/","name":"Marius Bancila","image":{"@type":"ImageObject","@id":"https:\/\/mariusbancila.ro\/blog\/2021\/12\/23\/use-cases-of-variable-templates-in-cpp\/#authorImage","url":"https:\/\/secure.gravatar.com\/avatar\/a84dd2831d955c38355ddea55df4df260809b88f36408bc14fd4eab8f7f131c9?s=96&d=mm&r=g","width":96,"height":96,"caption":"Marius Bancila"}},{"@type":"WebPage","@id":"https:\/\/mariusbancila.ro\/blog\/2021\/12\/23\/use-cases-of-variable-templates-in-cpp\/#webpage","url":"https:\/\/mariusbancila.ro\/blog\/2021\/12\/23\/use-cases-of-variable-templates-in-cpp\/","name":"Use Cases of Variable Templates in C++","description":"Learn about variable templates in C++ and how they help reduce template code and improve readability.","inLanguage":"en-US","isPartOf":{"@id":"https:\/\/mariusbancila.ro\/blog\/#website"},"breadcrumb":{"@id":"https:\/\/mariusbancila.ro\/blog\/2021\/12\/23\/use-cases-of-variable-templates-in-cpp\/#breadcrumblist"},"author":{"@id":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/#author"},"creator":{"@id":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/#author"},"datePublished":"2021-12-23T12:17:28+02:00","dateModified":"2021-12-23T22:35:31+02:00"},{"@type":"WebSite","@id":"https:\/\/mariusbancila.ro\/blog\/#website","url":"https:\/\/mariusbancila.ro\/blog\/","name":"Marius Bancila's Blog","description":"About code. Mostly on C++","inLanguage":"en-US","publisher":{"@id":"https:\/\/mariusbancila.ro\/blog\/#organization"}}]},"og:locale":"en_US","og:site_name":"Marius Bancila's Blog | About code. Mostly on C++","og:type":"article","og:title":"Use Cases of Variable Templates in C++","og:description":"Learn about variable templates in C++ and how they help reduce template code and improve readability.","og:url":"https:\/\/mariusbancila.ro\/blog\/2021\/12\/23\/use-cases-of-variable-templates-in-cpp\/","article:published_time":"2021-12-23T10:17:28+00:00","article:modified_time":"2021-12-23T20:35:31+00:00","twitter:card":"summary","twitter:title":"Use Cases of Variable Templates in C++","twitter:description":"Learn about variable templates in C++ and how they help reduce template code and improve readability."},"aioseo_meta_data":{"post_id":"4389","title":null,"description":"Learn about variable templates in C++ and how they help reduce template code and improve readability.","keywords":[],"keyphrases":{"focus":[],"additional":[]},"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":"","og_custom_url":null,"og_article_section":null,"og_article_tags":[],"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":{"id":"aioseo-article-6369651304eb5","slug":"article","graphName":"Article","label":"Article","properties":{"type":"BlogPosting","name":"#post_title","headline":"#post_title","description":"#post_excerpt","image":"","keywords":"","author":{"name":"#author_name","url":"#author_url"},"dates":{"include":true,"datePublished":"","dateModified":""}}},"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"Article","isEnabled":true},"graphs":[]},"schema_type":"default","schema_type_options":"{\"article\":{\"articleType\":\"BlogPosting\"},\"course\":{\"name\":\"\",\"description\":\"\",\"provider\":\"\"},\"faq\":{\"pages\":[]},\"product\":{\"reviews\":[]},\"recipe\":{\"ingredients\":[],\"instructions\":[],\"keywords\":[]},\"software\":{\"reviews\":[],\"operatingSystems\":[]},\"webPage\":{\"webPageType\":\"WebPage\"}}","pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":"-1","robots_max_videopreview":"-1","robots_max_imagepreview":"large","priority":null,"frequency":"default","location":null,"local_seo":null,"breadcrumb_settings":null,"limit_modified_date":false,"ai":null,"created":"2021-12-23 09:09:41","updated":"2025-12-12 07:56:25","seo_analyzer_scan_date":null,"focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"author_meta":{"display_name":"Marius Bancila","author_link":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/"},"featured_img":null,"jetpack_publicize_connections":[],"uagb_featured_image_src":{"full":false,"thumbnail":false,"medium":false,"medium_large":false,"large":false,"1536x1536":false,"2048x2048":false},"uagb_author_info":{"display_name":"Marius Bancila","author_link":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/"},"uagb_comment_info":0,"uagb_excerpt":"Since C++14 variables can also be templatized. A variable template defines a family of variable (when declared at namespace scope) or a family of static data members (when defined at class scope). The question is, what is the benefit of variable templates?","coauthors":[],"tax_additional":{"categories":{"linked":["<a href=\"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/c\/\" class=\"advgb-post-tax-term\">C++<\/a>"],"unlinked":["<span class=\"advgb-post-tax-term\">C++<\/span>"]},"tags":{"linked":["<a href=\"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/c\/\" class=\"advgb-post-tax-term\">C++<\/a>","<a href=\"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/c\/\" class=\"advgb-post-tax-term\">C++14<\/a>","<a href=\"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/c\/\" class=\"advgb-post-tax-term\">C++17<\/a>","<a href=\"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/c\/\" class=\"advgb-post-tax-term\">templates<\/a>"],"unlinked":["<span class=\"advgb-post-tax-term\">C++<\/span>","<span class=\"advgb-post-tax-term\">C++14<\/span>","<span class=\"advgb-post-tax-term\">C++17<\/span>","<span class=\"advgb-post-tax-term\">templates<\/span>"]}},"comment_count":"0","relative_dates":{"created":"Posted 5 years ago","modified":"Updated 5 years ago"},"absolute_dates":{"created":"Posted on December 23, 2021","modified":"Updated on December 23, 2021"},"absolute_dates_time":{"created":"Posted on December 23, 2021 12:17 pm","modified":"Updated on December 23, 2021 10:35 pm"},"featured_img_caption":"","series_order":"","jetpack_shortlink":"https:\/\/wp.me\/pYNdv-18N","jetpack_sharing_enabled":true,"jetpack_likes_enabled":true,"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/posts\/4389","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/comments?post=4389"}],"version-history":[{"count":5,"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/posts\/4389\/revisions"}],"predecessor-version":[{"id":4396,"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/posts\/4389\/revisions\/4396"}],"wp:attachment":[{"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/media?parent=4389"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/categories?post=4389"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/tags?post=4389"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}