{"id":8962,"date":"2024-01-22T10:20:57","date_gmt":"2024-01-22T10:20:57","guid":{"rendered":"https:\/\/www.modernescpp.com\/?p=8962"},"modified":"2024-01-22T10:20:58","modified_gmt":"2024-01-22T10:20:58","slug":"the-formatting-library-in-c20","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/the-formatting-library-in-c20\/","title":{"rendered":"The Formatting Library in C++20"},"content":{"rendered":"\n<p>Today, I will start a series about the formatting library in C++20. The series is based on my C++20 book.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"955\" height=\"392\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2024\/01\/TimelineCpp20CoreLanguage.png\" alt=\"\" class=\"wp-image-8964\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2024\/01\/TimelineCpp20CoreLanguage.png 955w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2024\/01\/TimelineCpp20CoreLanguage-300x123.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2024\/01\/TimelineCpp20CoreLanguage-768x315.png 768w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2024\/01\/TimelineCpp20CoreLanguage-705x289.png 705w\" sizes=\"auto, (max-width: 955px) 100vw, 955px\" \/><\/figure>\n\n\n\n<p>Although Peter Gottschling wrote two great blog posts about the formatting library in C++20 (&#8220;<a href=\"https:\/\/www.modernescpp.com\/index.php\/std-format-in-c-20\/\" data-type=\"link\" data-id=\"https:\/\/www.modernescpp.com\/index.php\/std-format-in-c-20\/\"><code>std::format <\/code>in C++20<\/a>&#8220;, &#8220;<a href=\"https:\/\/www.modernescpp.com\/index.php\/extend-std-format-in-c-20-for-user-defined-types\/\" data-type=\"link\" data-id=\"https:\/\/www.modernescpp.com\/index.php\/extend-std-format-in-c-20-for-user-defined-types\/\">C++20: Extend <\/a><a href=\"https:\/\/www.modernescpp.com\/index.php\/extend-std-format-in-c-20-for-user-defined-types\/\" data-type=\"link\" data-id=\"https:\/\/www.modernescpp.com\/index.php\/extend-std-format-in-c-20-for-user-defined-types\/\" target=\"_blank\" rel=\"noreferrer noopener\"><code>std::format<\/code> <\/a><a href=\"https:\/\/www.modernescpp.com\/index.php\/extend-std-format-in-c-20-for-user-defined-types\/\" data-type=\"link\" data-id=\"https:\/\/www.modernescpp.com\/index.php\/extend-std-format-in-c-20-for-user-defined-types\/\">for User-Defined Types<\/a>&#8220;, I will write about the formatting library again. The reason is simple: Peter&#8217;s post gave you a great introduction and overview. I want to present all the details so that you can use this post and the upcoming ones as a reference.<\/p>\n\n\n\n<p>C++20 supports the following formatting functions:<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"729\" height=\"229\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2024\/01\/FormattingFunctions.png\" alt=\"\" class=\"wp-image-8970\" style=\"width:550px\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2024\/01\/FormattingFunctions.png 729w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2024\/01\/FormattingFunctions-300x94.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2024\/01\/FormattingFunctions-705x221.png 705w\" sizes=\"auto, (max-width: 729px) 100vw, 729px\" \/><\/figure>\n\n\n\n<p>The functions <code>std::format<\/code> and <code>std::format_to<\/code> are functionally equivalent to their pendants<code> std::vformat<\/code> and <code>std::vformat_to<\/code>, but they differ in a few points:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>std::format<\/code>, <code>std::_format_to<\/code>, and <code>std::format_to_n: <\/code>They require a compile-time value as a<code> <\/code>format string. This format string can be a <code>constexpr <\/code>string or a string literal. <\/li>\n\n\n\n<li><code>std::vformat<\/code>, and <code>std::vformat_t<\/code>: It&#8217;s format string can be a lvalue. The arguments must be passed to the <code>variadic function std::make_format_args. e.g.: <\/code>std::vformat(formatString, std::make_format_args(args)).<\/li>\n<\/ul>\n\n\n\n<p>The formatting functions accept an arbitrary number of arguments. The following program gives a first impression of the functions <code>std::format<\/code>, <code>std::format_to<\/code>, and<code> std::format_to_n<\/code>.<\/p>\n\n\n\n<!-- HTML generated using hilite.me --><div style=\"background: #f0f3f3; overflow:auto;width:auto;gray;border-width:.1em .1em .1em .8em\"><pre style=\"margin: 0; line-height: 125%\"><span style=\"color: #0099FF; font-style: italic\">\/\/ format.cpp<\/span>\n\n<span style=\"color: #009999\">#include &lt;format&gt;<\/span>\n<span style=\"color: #009999\">#include &lt;iostream&gt;<\/span>\n<span style=\"color: #009999\">#include &lt;iterator&gt;<\/span>\n<span style=\"color: #009999\">#include &lt;string&gt;<\/span>\n \n<span style=\"color: #007788; font-weight: bold\">int<\/span> <span style=\"color: #CC00FF\">main<\/span>() {\n    \n    std<span style=\"color: #555555\">::<\/span>cout <span style=\"color: #555555\">&lt;&lt;<\/span> <span style=\"color: #CC3300\">&#39;\\n&#39;<\/span>;\n\n    std<span style=\"color: #555555\">::<\/span>cout <span style=\"color: #555555\">&lt;&lt;<\/span> std<span style=\"color: #555555\">::<\/span>format(<span style=\"color: #CC3300\">&quot;Hello, C++{}!<\/span><span style=\"color: #CC3300; font-weight: bold\">\\n<\/span><span style=\"color: #CC3300\">&quot;<\/span>, <span style=\"color: #CC3300\">&quot;20&quot;<\/span>) <span style=\"color: #555555\">&lt;&lt;<\/span> <span style=\"color: #CC3300\">&#39;\\n&#39;<\/span>;  <span style=\"color: #0099FF; font-style: italic\">\/\/ (1)<\/span>\n\n    std<span style=\"color: #555555\">::<\/span>string buffer;\n \n    std<span style=\"color: #555555\">::<\/span>format_to(                                             <span style=\"color: #0099FF; font-style: italic\">\/\/ (2)<\/span>\n        std<span style=\"color: #555555\">::<\/span>back_inserter(buffer), \n        <span style=\"color: #CC3300\">&quot;Hello, C++{}!<\/span><span style=\"color: #CC3300; font-weight: bold\">\\n<\/span><span style=\"color: #CC3300\">&quot;<\/span>,          \n        <span style=\"color: #CC3300\">&quot;20&quot;<\/span>);    \n        \n    std<span style=\"color: #555555\">::<\/span>cout <span style=\"color: #555555\">&lt;&lt;<\/span> buffer <span style=\"color: #555555\">&lt;&lt;<\/span> <span style=\"color: #CC3300\">&#39;\\n&#39;<\/span>;\n\n    buffer.clear(); \n\n    std<span style=\"color: #555555\">::<\/span>format_to_n(                                           <span style=\"color: #0099FF; font-style: italic\">\/\/ (3)<\/span>\n        std<span style=\"color: #555555\">::<\/span>back_inserter(buffer), <span style=\"color: #FF6600\">5<\/span>, \n        <span style=\"color: #CC3300\">&quot;Hello, C++{}!<\/span><span style=\"color: #CC3300; font-weight: bold\">\\n<\/span><span style=\"color: #CC3300\">&quot;<\/span>,          \n        <span style=\"color: #CC3300\">&quot;20&quot;<\/span>);    \n        \n    std<span style=\"color: #555555\">::<\/span>cout <span style=\"color: #555555\">&lt;&lt;<\/span> buffer <span style=\"color: #555555\">&lt;&lt;<\/span> <span style=\"color: #CC3300\">&#39;\\n&#39;<\/span>;\n\n    \n    std<span style=\"color: #555555\">::<\/span>cout <span style=\"color: #555555\">&lt;&lt;<\/span> <span style=\"color: #CC3300\">&#39;\\n&#39;<\/span>;\n   \n}\n<\/pre><\/div>\n\n\n\n<p>The program directly displays on line (1) the formatted string. However, the calls on lines (2) and (3) use a string as a buffer. Additionally,<code> std::format_to_n<\/code> pushes only five characters onto the buffer.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"368\" height=\"243\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2024\/01\/format.png\" alt=\"\" class=\"wp-image-8975\" style=\"width:350px\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2024\/01\/format.png 368w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2024\/01\/format-300x198.png 300w\" sizes=\"auto, (max-width: 368px) 100vw, 368px\" \/><\/figure>\n\n\n\n<p>Accordingly, here is the corresponding program using <code>std::vformat<\/code> and<code> std::vformat_n<\/code>.<\/p>\n\n\n\n<!-- HTML generated using hilite.me --><div style=\"background: #f0f3f3; overflow:auto;width:auto;gray;border-width:.1em .1em .1em .8em\"><pre style=\"margin: 0; line-height: 125%\"><span style=\"color: #0099FF; font-style: italic\">\/\/ formatRuntime.cpp<\/span>\n\n<span style=\"color: #009999\">#include &lt;format&gt;<\/span>\n<span style=\"color: #009999\">#include &lt;iostream&gt;<\/span>\n<span style=\"color: #009999\">#include &lt;iterator&gt;<\/span>\n<span style=\"color: #009999\">#include &lt;string&gt;<\/span>\n \n<span style=\"color: #007788; font-weight: bold\">int<\/span> <span style=\"color: #CC00FF\">main<\/span>() {\n    \n    std<span style=\"color: #555555\">::<\/span>cout <span style=\"color: #555555\">&lt;&lt;<\/span> <span style=\"color: #CC3300\">&#39;\\n&#39;<\/span>;\n\n    std<span style=\"color: #555555\">::<\/span>string formatString <span style=\"color: #555555\">=<\/span> <span style=\"color: #CC3300\">&quot;Hello, C++{}!<\/span><span style=\"color: #CC3300; font-weight: bold\">\\n<\/span><span style=\"color: #CC3300\">&quot;<\/span>;\n\n    std<span style=\"color: #555555\">::<\/span>cout <span style=\"color: #555555\">&lt;&lt;<\/span> std<span style=\"color: #555555\">::<\/span>vformat(formatString, std<span style=\"color: #555555\">::<\/span>make_format_args(<span style=\"color: #CC3300\">&quot;20&quot;<\/span>)) <span style=\"color: #555555\">&lt;&lt;<\/span> <span style=\"color: #CC3300\">&#39;\\n&#39;<\/span>;  <span style=\"color: #0099FF; font-style: italic\">\/\/ (1)<\/span>\n\n    std<span style=\"color: #555555\">::<\/span>string buffer;\n \n    std<span style=\"color: #555555\">::<\/span>vformat_to(                                                               <span style=\"color: #0099FF; font-style: italic\">\/\/ (2)<\/span>\n        std<span style=\"color: #555555\">::<\/span>back_inserter(buffer), \n        formatString,          \n        std<span style=\"color: #555555\">::<\/span>make_format_args(<span style=\"color: #CC3300\">&quot;20&quot;<\/span>));    \n        \n    std<span style=\"color: #555555\">::<\/span>cout <span style=\"color: #555555\">&lt;&lt;<\/span> buffer <span style=\"color: #555555\">&lt;&lt;<\/span> <span style=\"color: #CC3300\">&#39;\\n&#39;<\/span>;\n   \n}\n<\/pre><\/div>\n\n\n\n<p>The <code>formatString <\/code>in lines (1) and (2) is a lvalue.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"466\" height=\"210\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2024\/01\/formatRuntime.png\" alt=\"\" class=\"wp-image-8976\" style=\"width:448px\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2024\/01\/formatRuntime.png 466w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2024\/01\/formatRuntime-300x135.png 300w\" sizes=\"auto, (max-width: 466px) 100vw, 466px\" \/><\/figure>\n\n\n\n<p>Presumably, the most exciting part of the formatting functions is the format string (&#8220;<code>Hello, C++{}!\\n<\/code>&#8220;).<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Format String<\/h2>\n\n\n\n<p>The formatting string syntax is identical for the formatting functions <code>std::format<\/code>,<code> std::format_to<\/code>, <code>std::format_to_n<\/code>, <code>std::vformat<\/code>, and <code>std::vformat_to<\/code>. I use <code>std::format<\/code> in my examples.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Syntax: <strong><code>std::format(FormatString, Args)<\/code><\/strong><\/li>\n<\/ul>\n\n\n\n<p>The format string <strong><code>FormatString<\/code><\/strong> consists of<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Ordinary characters (except { and })<\/li>\n\n\n\n<li>Escape sequences {{ and }} that are replaced by { and }<\/li>\n\n\n\n<li>Replacement fields<\/li>\n<\/ul>\n\n\n\n<p>A replacement field has the format { }.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>You can use an argument id and a colon inside the replacement field followed by a format specification. Both components are optional.<\/li>\n<\/ul>\n\n\n\n<p>The argument id allows you to specify the index of the arguments in <strong><code>Args<\/code><\/strong>. The ids start with 0. When you don&#8217;t provide the argument id, the fields are filled in the same order as the arguments are given. Either all replacement fields have to use an argument id or none; i.e., <code>std::format(\"{}, {}\", \"Hello\", \"World\")<\/code> and <code>std::format(\"{1}, {0}\", \"World\", \"Hello\") <\/code>will both compile, but <code>std::format(\"{1}, {}\", \"World\", \"Hello\")<\/code> won&#8217;t. &nbsp;<\/p>\n\n\n\n<p><code>std::formatter<\/code> and its specializations define the format specification for the argument types.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Basic types and<code> std::string<\/code>: based on Python&#8217;s format specification<\/li>\n\n\n\n<li>Chrono types: I present them in an upcoming post.<\/li>\n\n\n\n<li>Other formattable types: User-defined<code> std::formatter<\/code> specialization. I will present them in an upcoming post.<\/li>\n<\/ul>\n\n\n\n<p>The fact that the format strings is a compile time variable, has two interesting consequences: performance and safety.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Compile Time<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Performance: \u00a0If the format string is checked at compile time, there is nothing to do at run time. Consequentially, the three functions <code>std::format<\/code>, <code>std::format_to,<\/code> and <code>std::format_to_n<\/code> promise excellent performance. The prototype library <a href=\"https:\/\/github.com\/fmtlib\/fmt\" data-type=\"link\" data-id=\"https:\/\/github.com\/fmtlib\/fmt)\">fmt<\/a> has a few exciting benchmarks.<\/li>\n\n\n\n<li>Safety: Using a wrong format string at compile time causes a compilation error. On the contrary, using a format string at run time with <code>std::vformat<\/code> or <code>std::vformat_to <\/code>causes a <code>std::format_error<\/code> exception.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">What&#8217;s Next?<\/h2>\n\n\n\n<p>I will use the next blog post to fill in the theory with practice. <\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Today, I will start a series about the formatting library in C++20. The series is based on my C++20 book. Although Peter Gottschling wrote two great blog posts about the formatting library in C++20 (&#8220;std::format in C++20&#8220;, &#8220;C++20: Extend std::format for User-Defined Types&#8220;, I will write about the formatting library again. The reason is simple: [&hellip;]<\/p>\n","protected":false},"author":21,"featured_media":8964,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[375],"tags":[454],"class_list":["post-8962","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-c-20","tag-format"],"_links":{"self":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/8962","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=8962"}],"version-history":[{"count":19,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/8962\/revisions"}],"predecessor-version":[{"id":8990,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/8962\/revisions\/8990"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media\/8964"}],"wp:attachment":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media?parent=8962"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=8962"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=8962"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}