{"id":5591,"date":"2018-12-27T08:29:16","date_gmt":"2018-12-27T08:29:16","guid":{"rendered":"https:\/\/www.modernescpp.com\/index.php\/c-core-guidelines-rules-for-variadic-templates\/"},"modified":"2023-06-26T10:17:04","modified_gmt":"2023-06-26T10:17:04","slug":"c-core-guidelines-rules-for-variadic-templates","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/c-core-guidelines-rules-for-variadic-templates\/","title":{"rendered":"C++ Core Guidelines: Rules for Variadic Templates"},"content":{"rendered":"<p>Variadic templates are a typical feature of C++: from the user&#8217;s perspective, they are easy to use, but from the implementor&#8217;s perspective, they look pretty scary. Today&#8217;s post is mainly about the implementor&#8217;s perspective.<\/p>\n<p><!--more--><\/p>\n<p>&nbsp;<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5587\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/12\/theater-311730_1280.png\" alt=\"theater 311730 1280\" width=\"400\" height=\"247\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/12\/theater-311730_1280.png 1280w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/12\/theater-311730_1280-300x185.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/12\/theater-311730_1280-1024x632.png 1024w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/12\/theater-311730_1280-768x474.png 768w\" sizes=\"auto, (max-width: 400px) 100vw, 400px\" \/><\/p>\n<p>Before I write about the details of variadic temples,&nbsp;I want to mention my introduction to this post briefly. I often wear two heads when I teach C++: one for the user and one for the implementor. Features such as templates are easy to use but challenging to implement. This significant gap is typically for C++ and, I assume, more profound than in other mainstream programming languages such as Python, Java, or C. Honestly, I have no problem with this gap. I call this gap abstraction, and it is an essential part of the power of C++. The art of the implementer of the library or framework is to provide easy-to-use (complicated to misuse) and stable interfaces.&nbsp; If you don&#8217;t get the point, wait for the next section, when I develop <span style=\"font-family: courier new, courier;\">std::make_unique<\/span>.<\/p>\n<p>Today&#8217;s post is based on three rules:<\/p>\n<ul>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rt-variadic\">T.100: Use variadic templates when you need a function that takes a variable number of arguments of a variety of types<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rt-variadic-pass\">T.101: ??? How to pass arguments to a variadic template ???<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rt-variadic-process\">T.102: ??? How to process arguments to a variadic template ???<\/a><\/li>\n<\/ul>\n<p>You can already guess it. The three rules are title-only; therefore, I make one story out of the first three.<\/p>\n<p>As promised, I want to develop <span style=\"font-family: courier new, courier;\">std::make_unique. std::make_unique<\/span> is a function template that returns a dynamically allocated object protected by a std<span style=\"font-family: courier new, courier;\">::unique_ptr<\/span>. Let me show you a few use cases.<span style=\"font-family: courier new, courier;\"><br \/><\/span><\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #0099ff; font-style: italic;\">\/\/ makeUnique.cpp<\/span>\r\n\r\n<span style=\"color: #009999;\">#include &lt;memory&gt;<\/span>\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">struct<\/span> MyType{\r\n    MyType(<span style=\"color: #007788; font-weight: bold;\">int<\/span>, <span style=\"color: #007788; font-weight: bold;\">double<\/span>, <span style=\"color: #007788; font-weight: bold;\">bool<\/span>){};\r\n};\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">int<\/span> <span style=\"color: #cc00ff;\">main<\/span>(){\r\n    \r\n    <span style=\"color: #007788; font-weight: bold;\">int<\/span> lvalue{<span style=\"color: #ff6600;\">2020<\/span>};\r\n    \r\n    std::unique_ptr&lt;int&gt; <span style=\"color: #555555;\"><\/span><span style=\"color: #555555;\"><\/span><span style=\"color: #007788; font-weight: bold;\"><\/span><span style=\"color: #555555;\"><\/span>uniqZero <span style=\"color: #555555;\">=<\/span> std<span style=\"color: #555555;\">::<\/span>make_unique<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">&gt;<\/span>();      <span style=\"color: #0099ff; font-style: italic;\">\/\/ (1)<\/span>\r\n    <span style=\"color: #006699; font-weight: bold;\">auto<\/span> uniqEleven <span style=\"color: #555555;\">=<\/span> std<span style=\"color: #555555;\">::<\/span>make_unique<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">&gt;<\/span>(<span style=\"color: #ff6600;\">2011<\/span>);                <span style=\"color: #0099ff; font-style: italic;\">\/\/ (2)<\/span>\r\n    <span style=\"color: #006699; font-weight: bold;\">auto<\/span> uniqTwenty <span style=\"color: #555555;\">=<\/span> std<span style=\"color: #555555;\">::<\/span>make_unique<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">&gt;<\/span>(lvalue);              <span style=\"color: #0099ff; font-style: italic;\">\/\/ (3)<\/span>\r\n    <span style=\"color: #006699; font-weight: bold;\">auto<\/span> uniqType <span style=\"color: #555555;\">=<\/span> std<span style=\"color: #555555;\">::<\/span>make_unique<span style=\"color: #555555;\">&lt;<\/span>MyType<span style=\"color: #555555;\">&gt;<\/span>(lvalue, <span style=\"color: #ff6600;\">3.14<\/span>, <span style=\"color: #336666;\">true<\/span>); <span style=\"color: #0099ff; font-style: italic;\">\/\/ (4)<\/span>\r\n    \r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>Based on this use case, what are the requirements of <span style=\"font-family: courier new, courier;\">std::make_unique<\/span>?<\/p>\n<ol>\n<li>It should deal with an arbitrary number of arguments. The<span style=\"font-family: courier new, courier;\"> std::make_unique<\/span> calls get 0, 1, and 3 arguments.<\/li>\n<li>It should deal with lvalues and rvalues. The<span style=\"font-family: courier new, courier;\"> std::make_unique call<\/span> in line (2) gets an rvalue and an lvalue in line (3). The last one even gets an rvalue and an lvalue.<\/li>\n<li>It should forward its arguments unchanged to the underlying constructor. This means the constructor of <span style=\"font-family: courier new, courier;\">std::unique_ptr<\/span> should get an lvalue\/rvalue if <span style=\"font-family: courier new, courier;\">std::make_unique<\/span> gets an lvalue\/rvalue.<\/li>\n<\/ol>\n<p>These requirements are typically for factory functions such as <span style=\"font-family: courier new, courier;\">std::make_unique, std::make_shared, std::make_tupl<\/span>e, and <span style=\"font-family: courier new, courier;\">std::thread. <\/span>Both rely on two powerful features of C++11:<\/p>\n<ol>\n<li>Variadic templates<\/li>\n<li>Perfect forwarding<\/li>\n<\/ol>\n<p>Now, I want to create my factory function<span style=\"font-family: courier new, courier;\"> createT.<\/span> Let me start with perfect forwarding.<\/p>\n<\/p>\n<h2>Perfect Forwarding<\/h2>\n<p>First of all: What is perfect forwarding?<\/p>\n<ul>\n<li><strong>Perfect forwarding<\/strong> allows you to preserve an argument\u2019s value category (lvalue\/rvalue) and <code>const<\/code>\/<code>volatile<\/code> modifiers.<\/li>\n<\/ul>\n<p>Perfect forwarding follows a typical pattern consisting of a universal reference and <span style=\"font-family: courier new, courier;\">std::forward.<\/span><\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #006699; font-weight: bold;\">template<\/span><span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #006699; font-weight: bold;\">typename<\/span> <span style=\"color: #00aa88; font-weight: bold;\">T<\/span><span style=\"color: #555555;\">&gt;<\/span>        <span style=\"color: #0099ff; font-style: italic;\">\/\/ (1)<\/span>\r\n<span style=\"color: #007788; font-weight: bold;\">void<\/span> create(T<span style=\"color: #555555;\">&amp;&amp;<\/span> t){         <span style=\"color: #0099ff; font-style: italic;\">\/\/ (2)<\/span>\r\n    std<span style=\"color: #555555;\">::<\/span>forward<span style=\"color: #555555;\">&lt;<\/span>T<span style=\"color: #555555;\">&gt;<\/span>(t);     <span style=\"color: #0099ff; font-style: italic;\">\/\/ (3)<\/span>\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>The three parts of the pattern to get perfect forwarding are:<\/p>\n<ol>\n<li>You need a template parameter T: <span style=\"font-family: courier new, courier;\">typename T<\/span><\/li>\n<li>Bind T by universal reference, also known as perfect forwarding reference: <span style=\"font-family: courier new, courier;\">T&amp;&amp; t<\/span><\/li>\n<li>Invoke <span style=\"font-family: courier new, courier;\">std::forward<\/span> on the argument: <span style=\"font-family: courier new, courier;\">std::forward&lt;T&gt;(t)<\/span><\/li>\n<\/ol>\n<p>The key observation is that T&amp;&amp; (line 2) can bind an lvalue or an rvalue and that <span style=\"font-family: courier new, courier;\">std::forward<\/span> (line 3) does the perfect forwarding.<\/p>\n<p>It&#8217;s time to create the prototype of the <span style=\"font-family: courier new, courier;\">createT<\/span> factory function, which should behave at the end, such as <span><span style=\"font-family: courier new, courier;\">makeUnique.cpp<\/span>. I just replaced <span style=\"font-family: courier new, courier;\">std::make_unique<\/span> with the <span style=\"font-family: courier new, courier;\">createT<\/span> call, added the <span style=\"font-family: courier new, courier;\">createT<\/span> factory function, and commented the lines (1) and (4) out. Additionally, I removed the header <span style=\"font-family: courier new, courier;\">&lt;memory&gt;<\/span> (<span style=\"font-family: courier new, courier;\">std::make_unique<\/span>) and added the header <span style=\"font-family: courier new, courier;\">&lt;utility&gt;<\/span>(<span style=\"font-family: courier new, courier;\">std::foward<\/span>).<br \/><\/span><\/p>\n<p>&nbsp;<\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #0099ff; font-style: italic;\">\/\/ createT1.cpp<\/span>\r\n\r\n<span style=\"color: #009999;\">#include &lt;utility&gt;<\/span>\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">struct<\/span> MyType{\r\n    MyType(<span style=\"color: #007788; font-weight: bold;\">int<\/span>, <span style=\"color: #007788; font-weight: bold;\">double<\/span>, <span style=\"color: #007788; font-weight: bold;\">bool<\/span>){};\r\n};\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">template<\/span> <span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #006699; font-weight: bold;\">typename<\/span> T, <span style=\"color: #006699; font-weight: bold;\">typename<\/span> Arg<span style=\"color: #555555;\">&gt;<\/span>\r\nT createT(Arg<span style=\"color: #555555;\">&amp;&amp;<\/span> arg){\r\n    <span style=\"color: #006699; font-weight: bold;\">return<\/span> T(std<span style=\"color: #555555;\">::<\/span>forward<span style=\"color: #555555;\">&lt;<\/span>Arg<span style=\"color: #555555;\">&gt;<\/span>(arg));\r\n}\r\n    \r\n<span style=\"color: #007788; font-weight: bold;\">int<\/span> main(){\r\n    \r\n    <span style=\"color: #007788; font-weight: bold;\">int<\/span> lvalue{<span style=\"color: #ff6600;\">2020<\/span>};\r\n    \r\n    <span style=\"color: #0099ff; font-style: italic;\">\/\/std::unique_ptr&lt;int&gt; uniqZero = std::make_unique&lt;int&gt;();      \/\/ (1)<\/span>\r\n    <span style=\"color: #006699; font-weight: bold;\">auto<\/span> uniqEleven <span style=\"color: #555555;\">=<\/span> createT<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">&gt;<\/span>(<span style=\"color: #ff6600;\">2011<\/span>);                <span style=\"color: #0099ff; font-style: italic;\">\/\/ (2)<\/span>\r\n    <span style=\"color: #006699; font-weight: bold;\">auto<\/span> uniqTwenty <span style=\"color: #555555;\">=<\/span> createT<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">&gt;<\/span>(lvalue);              <span style=\"color: #0099ff; font-style: italic;\">\/\/ (3)<\/span>\r\n    <span style=\"color: #0099ff; font-style: italic;\">\/\/auto uniqType = std::make_unique&lt;MyType&gt;(lvalue, 3.14, true); \/\/ (4)<\/span>\r\n    \r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>Fine. An rvalue (line 2) and an lvalue (line 3) pass my test.<\/p>\n<h2>Variadic Templates<\/h2>\n<p>Sometimes dots are essential. Putting exactly nine dots at the right place and line (1) and line (4) work.<\/p>\n<p>&nbsp;<\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #0099ff; font-style: italic;\">\/\/ createT2.cpp<\/span>\r\n\r\n<span style=\"color: #009999;\">#include &lt;utility&gt;<\/span>\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">struct<\/span> MyType{\r\n    MyType(<span style=\"color: #007788; font-weight: bold;\">int<\/span>, <span style=\"color: #007788; font-weight: bold;\">double<\/span>, <span style=\"color: #007788; font-weight: bold;\">bool<\/span>){};\r\n};\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">template<\/span> <span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #006699; font-weight: bold;\">typename<\/span> T, <span style=\"color: #006699; font-weight: bold;\">typename<\/span> ... Args<span style=\"color: #555555;\">&gt;<\/span>\r\nT createT(Args<span style=\"color: #555555;\">&amp;&amp;<\/span> ... args){\r\n    <span style=\"color: #006699; font-weight: bold;\">return<\/span> T(std<span style=\"color: #555555;\">::<\/span>forward<span style=\"color: #555555;\">&lt;<\/span>Args<span style=\"color: #555555;\">&gt;<\/span>(args) ... );\r\n}\r\n    \r\n<span style=\"color: #007788; font-weight: bold;\">int<\/span> main(){\r\n    \r\n    <span style=\"color: #007788; font-weight: bold;\">int<\/span> lvalue{<span style=\"color: #ff6600;\">2020<\/span>};\r\n    \r\n    <span style=\"color: #007788; font-weight: bold;\">int<\/span> uniqZero <span style=\"color: #555555;\">=<\/span> createT<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">&gt;<\/span>();                       <span style=\"color: #0099ff; font-style: italic;\">\/\/ (1)<\/span>\r\n    <span style=\"color: #006699; font-weight: bold;\">auto<\/span> uniqEleven <span style=\"color: #555555;\">=<\/span> createT<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">&gt;<\/span>(<span style=\"color: #ff6600;\">2011<\/span>);                <span style=\"color: #0099ff; font-style: italic;\">\/\/ (2)<\/span>\r\n    <span style=\"color: #006699; font-weight: bold;\">auto<\/span> uniqTwenty <span style=\"color: #555555;\">=<\/span> createT<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">&gt;<\/span>(lvalue);              <span style=\"color: #0099ff; font-style: italic;\">\/\/ (3)<\/span>\r\n    <span style=\"color: #006699; font-weight: bold;\">auto<\/span> uniqType <span style=\"color: #555555;\">=<\/span> createT<span style=\"color: #555555;\">&lt;<\/span>MyType<span style=\"color: #555555;\">&gt;<\/span>(lvalue, <span style=\"color: #ff6600;\">3.14<\/span>, <span style=\"color: #336666;\">true<\/span>); <span style=\"color: #0099ff; font-style: italic;\">\/\/ (4)<\/span>\r\n    \r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>How does the magic work? The three dots stand for an ellipse. By using them <span style=\"font-family: courier new, courier;\">Args,<\/span> or <span style=\"font-family: courier new, courier;\">args<\/span> become a parameter pack. To be more precise, <span style=\"font-family: courier new, courier;\">Args i<\/span>s a template parameter pack, and<span style=\"font-family: courier new, courier;\"> args<\/span> is a function parameter pack. You can only apply two operations to a parameter pack: you can pack or unpack it. If the ellipse is left of <span style=\"font-family: courier new, courier;\">Args<\/span> the parameter pack is packed; if the ellipse is right of <span style=\"font-family: courier new, courier;\">Args<\/span> the parameter pack is unpacked. In the case of the expression<span style=\"font-family: courier new, courier;\"> (std::forward&lt;Args&gt;(args)&#8230;<\/span>) this means the expression is unpacked until the parameter pack is consumed, and a comma is just placed between the unpacked components. This was all.<\/p>\n<p><a href=\"https:\/\/cppinsights.io\/\">CppInsight<\/a> helps you to look under the curtain.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5588\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/12\/createT2_1.png\" alt=\"createT2 1\" width=\"300\" height=\"233\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/12\/createT2_1.png 460w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/12\/createT2_1-300x233.png 300w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5589\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/12\/createT2_2.png\" alt=\"createT2 2\" width=\"600\" height=\"244\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/12\/createT2_2.png 870w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/12\/createT2_2-300x122.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/12\/createT2_2-768x312.png 768w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><\/p>\n<p>Now, I&#8217;m nearly done. Here is my <span style=\"font-family: courier new, courier;\">createT<\/span> factory function.<\/p>\n<p>&nbsp;<\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #006699; font-weight: bold;\">template<\/span> <span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #006699; font-weight: bold;\">typename<\/span> T, <span style=\"color: #006699; font-weight: bold;\">typename<\/span> ... Args<span style=\"color: #555555;\">&gt;<\/span>\r\nT createT(Args<span style=\"color: #555555;\">&amp;&amp;<\/span> ... args){\r\n    <span style=\"color: #006699; font-weight: bold;\">return<\/span> T(std<span style=\"color: #555555;\">::<\/span>forward<span style=\"color: #555555;\">&lt;<\/span>Args<span style=\"color: #555555;\">&gt;<\/span>(args) ... );\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>The two missing steps are.<\/p>\n<ol>\n<li>Create a <span style=\"font-family: courier new, courier;\">std::unique_ptr&lt;T&gt;<\/span> instead of a plain<span style=\"font-family: courier new, courier;\"> T<\/span><\/li>\n<li>Rename my function <span style=\"font-family: courier new, courier;\">make_unique. <\/span><\/li>\n<\/ol>\n<p>I&#8217;m done.<\/p>\n<h2>std::make_unique<\/h2>\n<p>&nbsp;<\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #006699; font-weight: bold;\">template<\/span> <span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #006699; font-weight: bold;\">typename<\/span> T, <span style=\"color: #006699; font-weight: bold;\">typename<\/span> ... Args<span style=\"color: #555555;\">&gt;<\/span>\r\nstd<span style=\"color: #555555;\">::<\/span>unique_ptr<span style=\"color: #555555;\">&lt;<\/span>T<span style=\"color: #555555;\">&gt;<\/span> make_unique(Args<span style=\"color: #555555;\">&amp;&amp;<\/span> ... args){\r\n    <span style=\"color: #006699; font-weight: bold;\">return<\/span> std<span style=\"color: #555555;\">::<\/span>unique_ptr<span style=\"color: #555555;\">&lt;<\/span>T<span style=\"color: #555555;\">&gt;<\/span>(<span style=\"color: #006699; font-weight: bold;\">new<\/span> T(std<span style=\"color: #555555;\">::<\/span>forward<span style=\"color: #555555;\">&lt;<\/span>Args<span style=\"color: #555555;\">&gt;<\/span>(args) ... ));\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>I forgot to scare you. Here is the scary part of my post.<\/p>\n<h2>printf<\/h2>\n<p>Of course, you know the C function <span style=\"font-family: courier new, courier;\">printf.<\/span> This is its signature: <span class=\"mw-geshi cpp source-cpp\"><span style=\"font-family: courier new, courier;\"><span class=\"kw4\">int<\/span> printf<span class=\"br0\">(<\/span> <span class=\"kw4\">const<\/span> <span class=\"kw4\">char<\/span><span class=\"sy2\">*<\/span> format, &#8230; <span class=\"br0\">)<\/span><\/span><span class=\"sy4\"><span style=\"font-family: courier new, courier;\">;. printf<\/span> is a function that can get an arbitrary number of arguments. Its power is based on the macro <a href=\"https:\/\/en.cppreference.com\/w\/cpp\/utility\/variadic\/va_arg\">va_arg <\/a>and is, therefore, not typesafe. <br \/><\/span><\/span><\/p>\n<p>Thanks to variadic templates, <span style=\"font-family: courier new, courier;\">printf<\/span> can be rewritten in a typesafe way.<\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #0099ff; font-style: italic;\">\/\/ myPrintf.cpp<\/span>\r\n\r\n<span style=\"color: #009999;\">#include &lt;iostream&gt;<\/span>\r\n \r\n<span style=\"color: #007788; font-weight: bold;\">void<\/span> <span style=\"color: #cc00ff;\">myPrintf<\/span>(<span style=\"color: #006699; font-weight: bold;\">const<\/span> <span style=\"color: #007788; font-weight: bold;\">char<\/span><span style=\"color: #555555;\">*<\/span> format){                           <span style=\"color: #0099ff; font-style: italic;\">\/\/ (3)<\/span>\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> format;\r\n}\r\n \r\n<span style=\"color: #006699; font-weight: bold;\">template<\/span><span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #006699; font-weight: bold;\">typename<\/span> T, <span style=\"color: #006699; font-weight: bold;\">typename<\/span> ... Args<span style=\"color: #555555;\">&gt;<\/span>\r\n<span style=\"color: #007788; font-weight: bold;\">void<\/span> myPrintf(<span style=\"color: #006699; font-weight: bold;\">const<\/span> <span style=\"color: #007788; font-weight: bold;\">char<\/span><span style=\"color: #555555;\">*<\/span> format, T value, Args ... args){   <span style=\"color: #0099ff; font-style: italic;\">\/\/ (4)<\/span>\r\n    <span style=\"color: #006699; font-weight: bold;\">for<\/span> ( ; <span style=\"color: #555555;\">*<\/span>format <span style=\"color: #555555;\">!=<\/span> <span style=\"color: #cc3300;\">'\\0'<\/span>; format<span style=\"color: #555555;\">++<\/span> ) {                    <span style=\"color: #0099ff; font-style: italic;\">\/\/ (5)<\/span>\r\n        <span style=\"color: #006699; font-weight: bold;\">if<\/span> ( <span style=\"color: #555555;\">*<\/span>format <span style=\"color: #555555;\">==<\/span> <span style=\"color: #cc3300;\">'%'<\/span> ) {                              <span style=\"color: #0099ff; font-style: italic;\">\/\/ (6) <\/span>\r\n           std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> value;\r\n           myPrintf(format <span style=\"color: #555555;\">+<\/span> <span style=\"color: #ff6600;\">1<\/span>, args ... );                  <span style=\"color: #0099ff; font-style: italic;\">\/\/ (7)<\/span>\r\n           <span style=\"color: #006699; font-weight: bold;\">return<\/span>;\r\n        }\r\n        std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #555555;\">*<\/span>format;                                <span style=\"color: #0099ff; font-style: italic;\">\/\/ (8)<\/span>\r\n    }\r\n}\r\n \r\n<span style=\"color: #007788; font-weight: bold;\">int<\/span> main(){\r\n    \r\n    myPrintf(<span style=\"color: #cc3300;\">\"<\/span><span style=\"color: #cc3300; font-weight: bold;\">\\n<\/span><span style=\"color: #cc3300;\">\"<\/span>);                                          <span style=\"color: #0099ff; font-style: italic;\">\/\/ (1)<\/span>\r\n    \r\n    myPrintf(<span style=\"color: #cc3300;\">\"% world% %<\/span><span style=\"color: #cc3300; font-weight: bold;\">\\n<\/span><span style=\"color: #cc3300;\">\"<\/span>, <span style=\"color: #cc3300;\">\"Hello\"<\/span>, <span style=\"color: #cc3300;\">'!'<\/span>, <span style=\"color: #ff6600;\">2011<\/span>);            <span style=\"color: #0099ff; font-style: italic;\">\/\/ (2)<\/span>\r\n    \r\n    myPrintf(<span style=\"color: #cc3300;\">\"<\/span><span style=\"color: #cc3300; font-weight: bold;\">\\n<\/span><span style=\"color: #cc3300;\">\"<\/span>);                                          \r\n    \r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>How does the code work? If <span style=\"font-family: courier new, courier;\">myPrintf<\/span> is invoked with only a format string (line 1), line (3) is used. In the case of line (2), the function template (line 4) is applied. The function templates loops (line 5) as long as the format symbol does not equal <span style=\"font-family: courier new, courier;\">`\\0`<\/span>. Two control flows are possible if the format symbol is not equal to `\\0`. First, if the format starts with &#8216;<span style=\"font-family: 'courier new', courier;\">%<\/span>&#8216;&nbsp; (line 6), the first argument <span style=\"font-family: courier new, courier;\">value<\/span> is displayed<span style=\"font-family: courier new, courier;\">, <\/span>and <span style=\"font-family: courier new, courier;\">myPrintf<\/span> is once more invoked, but this time with a new format symbol and an argument less (line 7). Second, the format symbol is displayed if the format string does not start with &#8216;%&#8217; (line 8). The function <span style=\"font-family: courier new, courier;\">myPrintf<\/span> (line 3) is the end condition for the recursive calls.<\/p>\n<p>The output of the program is as expected.<\/p>\n<h2>&nbsp;<img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5590\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/12\/myPrintf.png\" alt=\"myPrintf\" width=\"250\" height=\"156\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/12\/myPrintf.png 331w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/12\/myPrintf-300x187.png 300w\" sizes=\"auto, (max-width: 250px) 100vw, 250px\" \/><\/h2>\n<h2>What&#8217;s next?<\/h2>\n<p>One rule to variadic templates is left. Afterward, the guidelines continue with template metaprogramming. I&#8217;m unsure how deep I should dive into template metaprogramming in my next post.<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Variadic templates are a typical feature of C++: from the user&#8217;s perspective, they are easy to use, but from the implementor&#8217;s perspective, they look pretty scary. Today&#8217;s post is mainly about the implementor&#8217;s perspective.<\/p>\n","protected":false},"author":21,"featured_media":5587,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[372],"tags":[441],"class_list":["post-5591","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-modern-c","tag-variadic-templates"],"_links":{"self":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5591","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/users\/21"}],"replies":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/comments?post=5591"}],"version-history":[{"count":1,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5591\/revisions"}],"predecessor-version":[{"id":6800,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5591\/revisions\/6800"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media\/5587"}],"wp:attachment":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media?parent=5591"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=5591"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=5591"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}