{"id":9091,"date":"2024-02-12T09:37:37","date_gmt":"2024-02-12T09:37:37","guid":{"rendered":"https:\/\/www.modernescpp.com\/?p=9091"},"modified":"2024-02-12T09:37:38","modified_gmt":"2024-02-12T09:37:38","slug":"formatting-user-defined-types-in-c20","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/formatting-user-defined-types-in-c20\/","title":{"rendered":"Formatting User-Defined Types in C++20"},"content":{"rendered":"\n<p>Additionally, to the basic types and <code>std::string<\/code>, you can also format user-defined types in C++20.<\/p>\n\n\n\n<figure class=\"wp-block-image 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>So far, I have formatted basic types and<code> std::string.<\/code> Here are my previous posts:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/www.modernescpp.com\/index.php\/the-formatting-library-in-c20\/\">The Formatting Library in C++20<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/www.modernescpp.com\/index.php\/the-formatting-library-in-c20-the-format-string\/\">The Formatting Library in C++20: The Format String<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/www.modernescpp.com\/index.php\/the-formatting-library-in-c20-the-format-string-2\/\">The Formatting Library in C++20: The Format String (2)<\/a><\/li>\n<\/ul>\n\n\n\n<p><code>std::formatter<\/code> enables it to format user-defined types. You have to specialize the class <a href=\"https:\/\/en.cppreference.com\/w\/cpp\/utility\/format\/formatter\">std::formatter<\/a> for the user-defined type. In particular, you must implement the member functions <code>parse<\/code>, and <code>format<\/code>.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong><code>parse<\/code><\/strong>: &nbsp;This function parses the format string and throws a <code>std::format_error<\/code> in case of an error.<\/li>\n<\/ul>\n\n\n\n<p>The function <code>parse <\/code>should be <code>constexpr <\/code>to enable compile-time parsing. It accepts a parse context (<code>std::format_parse_context<\/code>) and should return the last character for the format specifier (the closing }). When you don&#8217;t use a format specifier, this is also the first character of the format specifier.<\/p>\n\n\n\n<p>The following lines show a few examples of the first character of the format specifier:<\/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: #CC3300\">&quot;{}&quot;<\/span>          <span style=\"color: #0099FF; font-style: italic\">\/\/ context.begin() points to }<\/span>\n<span style=\"color: #CC3300\">&quot;{:}&quot;<\/span>         <span style=\"color: #0099FF; font-style: italic\">\/\/ context.begin() points to }<\/span>\n<span style=\"color: #CC3300\">&quot;{0:d}&quot;<\/span>       <span style=\"color: #0099FF; font-style: italic\">\/\/ context.begin() points to d} <\/span>\n<span style=\"color: #CC3300\">&quot;{:5.3f}&quot;<\/span>     <span style=\"color: #0099FF; font-style: italic\">\/\/ context.begin() points to: 5.3f}<\/span>\n<span style=\"color: #CC3300\">&quot;{:x}&quot;<\/span>        <span style=\"color: #0099FF; font-style: italic\">\/\/ context.begin() points to x} <\/span>\n<span style=\"color: #CC3300\">&quot;{0} {0}&quot;<\/span>     <span style=\"color: #0099FF; font-style: italic\">\/\/ context.begin() points to: &quot;} {0}&quot;<\/span>\n<\/pre><\/div>\n\n\n\n<p><code>context.begin() <\/code>points to the first character of the format specifier and <code>context.end()<\/code> to the last character of the entire format string. When you provide a format specifier, you have to parse all between <code>context.begin()<\/code> and <code>context.end()<\/code> and return the position of the closing<code> }<\/code>.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code><strong>format<\/strong><\/code>: This function should be <code>const<\/code>. It gets the value <code>val<\/code>, and the format context<code> context. format <\/code>formats the value <code>val<\/code>, and writes it according to the parsed format to<code> context.out(). <\/code>The<code> context.out()<\/code> return value can be directly fed into <code>std::format_to. std::format_to<\/code> has to return the new position for further output. It returns an iterator that represents the end of the output.<\/li>\n<\/ul>\n\n\n\n<p>Let me apply the theory and start with the first example.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">A Formatter for a Single Value<\/h2>\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\">\/\/ formatSingleValue.cpp<\/span>\n\n<span style=\"color: #009999\">#include &lt;format&gt;<\/span>\n<span style=\"color: #009999\">#include &lt;iostream&gt;<\/span>\n\n<span style=\"color: #006699; font-weight: bold\">class<\/span> <span style=\"color: #00AA88; font-weight: bold\">SingleValue<\/span> {                                          <span style=\"color: #0099FF; font-style: italic\">\/\/ (1)<\/span>\n <span style=\"color: #9999FF\">public:<\/span> \n   SingleValue() <span style=\"color: #555555\">=<\/span> <span style=\"color: #006699; font-weight: bold\">default<\/span>;\n   <span style=\"color: #006699; font-weight: bold\">explicit<\/span> SingleValue(<span style=\"color: #007788; font-weight: bold\">int<\/span> s)<span style=\"color: #555555\">:<\/span> singleValue{s} {}\n   <span style=\"color: #007788; font-weight: bold\">int<\/span> getValue() <span style=\"color: #006699; font-weight: bold\">const<\/span> {                                    <span style=\"color: #0099FF; font-style: italic\">\/\/ (2)<\/span>\n     <span style=\"color: #006699; font-weight: bold\">return<\/span> singleValue;\n   }\n <span style=\"color: #9999FF\">private:<\/span>\n   <span style=\"color: #007788; font-weight: bold\">int<\/span> singleValue{};\n};\n\n<span style=\"color: #006699; font-weight: bold\">template<\/span><span style=\"color: #555555\">&lt;&gt;<\/span>                                                   <span style=\"color: #0099FF; font-style: italic\">\/\/ (3)<\/span>\n<span style=\"color: #006699; font-weight: bold\">struct<\/span> std<span style=\"color: #555555\">::<\/span>formatter<span style=\"color: #555555\">&lt;<\/span>SingleValue<span style=\"color: #555555\">&gt;<\/span> {\n  constexpr <span style=\"color: #006699; font-weight: bold\">auto<\/span> parse(std<span style=\"color: #555555\">::<\/span>format_parse_context<span style=\"color: #555555\">&amp;<\/span> context) { <span style=\"color: #0099FF; font-style: italic\">\/\/ (4)<\/span>\n    <span style=\"color: #006699; font-weight: bold\">return<\/span> context.begin();\n  }\n  <span style=\"color: #006699; font-weight: bold\">auto<\/span> format(<span style=\"color: #006699; font-weight: bold\">const<\/span> SingleValue<span style=\"color: #555555\">&amp;<\/span> sVal, std<span style=\"color: #555555\">::<\/span>format_context<span style=\"color: #555555\">&amp;<\/span> context) <span style=\"color: #006699; font-weight: bold\">const<\/span> {  <span style=\"color: #0099FF; font-style: italic\">\/\/ (5)<\/span>\n    <span style=\"color: #006699; font-weight: bold\">return<\/span> std<span style=\"color: #555555\">::<\/span>format_to(context.out(), <span style=\"color: #CC3300\">&quot;{}&quot;<\/span>, sVal.getValue());\n  }\n};\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  SingleValue sVal0;\n  SingleValue sVal2020{<span style=\"color: #FF6600\">2020<\/span>};\n  SingleValue sVal2023{<span style=\"color: #FF6600\">2023<\/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;Single Value: {} {} {}<\/span><span style=\"color: #CC3300; font-weight: bold\">\\n<\/span><span style=\"color: #CC3300\">&quot;<\/span>, sVal0, sVal2020, sVal2023);\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;Single Value: {1} {1} {1}<\/span><span style=\"color: #CC3300; font-weight: bold\">\\n<\/span><span style=\"color: #CC3300\">&quot;<\/span>, sVal0, sVal2020, sVal2023);\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;Single Value: {2} {1} {0}<\/span><span style=\"color: #CC3300; font-weight: bold\">\\n<\/span><span style=\"color: #CC3300\">&quot;<\/span>, sVal0, sVal2020, sVal2023);\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><code>SingleValue <\/code>(line 1) is a class having only one value. The member function <code>getValue <\/code>(line 2) returns this value. I specialize <code>std::formatter <\/code>(line 3) on <code>SingleValue<\/code>. This specialization has the member functions <code>parse <\/code>(line 4) and <code>format <\/code>(line 5). <code>parse <\/code>returns the end of the format specification. The end of the format specification is the closing }. <code>format <\/code>formats the value, and <code>context.ou<\/code>t creates an object passed to <code>std::format_to. format <\/code>returns the new position for further output.<\/p>\n\n\n\n<p>Executing this program gives the expected result:<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"466\" height=\"229\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2024\/02\/formatSingleValue.png\" alt=\"\" class=\"wp-image-9103\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2024\/02\/formatSingleValue.png 466w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2024\/02\/formatSingleValue-300x147.png 300w\" sizes=\"auto, (max-width: 466px) 100vw, 466px\" \/><\/figure>\n\n\n\n<p id=\"block-aea6d0eb-1aba-482f-8cc1-e3be644d2c60\">This formatter has a severe drawback. It does not support a format specifier. Let me improve that.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"block-e9774fdb-129d-4596-ba84-a78bb5294c60\">A Formatter Supporting a Format Specifier<\/h2>\n\n\n\n<p id=\"block-15608371-a80c-4123-8236-68c897bec76f\">Implementing a formatter for a user-defined type is pretty straightforward when you base your formatter on a standard formatter. Basing a user-defined formatter on a standard formatter can be done in two ways:&nbsp;delegation and inheritance.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Delegation<\/h3>\n\n\n\n<p>The following formatter delegates its job to a standard formatter.<\/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\">\/\/ formatSingleValueDelegation.cpp<\/span>\n\n<span style=\"color: #009999\">#include &lt;format&gt;<\/span>\n<span style=\"color: #009999\">#include &lt;iostream&gt;<\/span>\n\n<span style=\"color: #006699; font-weight: bold\">class<\/span> <span style=\"color: #00AA88; font-weight: bold\">SingleValue<\/span> {\n <span style=\"color: #9999FF\">public:<\/span> \n    SingleValue() <span style=\"color: #555555\">=<\/span> <span style=\"color: #006699; font-weight: bold\">default<\/span>;\n    <span style=\"color: #006699; font-weight: bold\">explicit<\/span> SingleValue(<span style=\"color: #007788; font-weight: bold\">int<\/span> s)<span style=\"color: #555555\">:<\/span> singleValue{s} {}\n    <span style=\"color: #007788; font-weight: bold\">int<\/span> getValue() <span style=\"color: #006699; font-weight: bold\">const<\/span> {\n        <span style=\"color: #006699; font-weight: bold\">return<\/span> singleValue;\n    }\n <span style=\"color: #9999FF\">private:<\/span>\n    <span style=\"color: #007788; font-weight: bold\">int<\/span> singleValue{};\n};\n\n<span style=\"color: #006699; font-weight: bold\">template<\/span><span style=\"color: #555555\">&lt;&gt;<\/span>                                                         <span style=\"color: #0099FF; font-style: italic\">\/\/ (1)<\/span>\n<span style=\"color: #006699; font-weight: bold\">struct<\/span> std<span style=\"color: #555555\">::<\/span>formatter<span style=\"color: #555555\">&lt;<\/span>SingleValue<span style=\"color: #555555\">&gt;<\/span> {\n\n    std<span style=\"color: #555555\">::<\/span>formatter<span style=\"color: #555555\">&lt;<\/span><span style=\"color: #007788; font-weight: bold\">int<\/span><span style=\"color: #555555\">&gt;<\/span> formatter;                                 <span style=\"color: #0099FF; font-style: italic\">\/\/ (2)<\/span>\n\n    constexpr <span style=\"color: #006699; font-weight: bold\">auto<\/span> <span style=\"color: #CC00FF\">parse<\/span>(std<span style=\"color: #555555\">::<\/span>format_parse_context<span style=\"color: #555555\">&amp;<\/span> context) {\n        <span style=\"color: #006699; font-weight: bold\">return<\/span> formatter.parse(context);                           <span style=\"color: #0099FF; font-style: italic\">\/\/ (3)<\/span>\n    }\n\n    <span style=\"color: #006699; font-weight: bold\">auto<\/span> <span style=\"color: #CC00FF\">format<\/span>(<span style=\"color: #006699; font-weight: bold\">const<\/span> SingleValue<span style=\"color: #555555\">&amp;<\/span> singleValue, std<span style=\"color: #555555\">::<\/span>format_context<span style=\"color: #555555\">&amp;<\/span> context) <span style=\"color: #006699; font-weight: bold\">const<\/span> {\n        <span style=\"color: #006699; font-weight: bold\">return<\/span> formatter.format(singleValue.getValue(), context);  <span style=\"color: #0099FF; font-style: italic\">\/\/ (4)<\/span>\n    }\n\n}; \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    SingleValue singleValue0;\n    SingleValue singleValue2020{<span style=\"color: #FF6600\">2020<\/span>};\n    SingleValue singleValue2023{<span style=\"color: #FF6600\">2023<\/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;{:*&lt;10}&quot;<\/span>, singleValue0) <span style=\"color: #555555\">&lt;&lt;<\/span> <span style=\"color: #CC3300\">&#39;\\n&#39;<\/span>;\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;{:*^10}&quot;<\/span>, singleValue2020) <span style=\"color: #555555\">&lt;&lt;<\/span> <span style=\"color: #CC3300\">&#39;\\n&#39;<\/span>;\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;{:*&gt;10}&quot;<\/span>, singleValue2023) <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> <span style=\"color: #CC3300\">&#39;\\n&#39;<\/span>;\n\n}\n<\/pre><\/div>\n\n\n\n<p><code>std::formatter&lt;SingleValue&gt;<\/code> (line 1) has a standard formatter for <code>int: std::formatter&lt;int&gt; formatter<\/code> (line 2). I delegate the parsing job to the formatter (line 3). Accordingly, the formatting job format is also delegated to the formatter (line 4).<\/p>\n\n\n\n<p>The program&#8217;s output shows that the formatter supports fill characters and alignment.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"529\" height=\"210\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2024\/02\/formatSingleValueDelegation.png\" alt=\"\" class=\"wp-image-9111\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2024\/02\/formatSingleValueDelegation.png 529w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2024\/02\/formatSingleValueDelegation-300x119.png 300w\" sizes=\"auto, (max-width: 529px) 100vw, 529px\" \/><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Inheritance<\/h3>\n\n\n\n<p>Thanks to inheritance, implementing the formatter for the user-defined type <code>SingleValue<\/code> is a piece of cake.<\/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\">\/\/ formatSingleValueInheritance.cpp<\/span>\n\n<span style=\"color: #009999\">#include &lt;format&gt;<\/span>\n<span style=\"color: #009999\">#include &lt;iostream&gt;<\/span>\n\n<span style=\"color: #006699; font-weight: bold\">class<\/span> <span style=\"color: #00AA88; font-weight: bold\">SingleValue<\/span> {\n <span style=\"color: #9999FF\">public:<\/span> \n    SingleValue() <span style=\"color: #555555\">=<\/span> <span style=\"color: #006699; font-weight: bold\">default<\/span>;\n    <span style=\"color: #006699; font-weight: bold\">explicit<\/span> SingleValue(<span style=\"color: #007788; font-weight: bold\">int<\/span> s)<span style=\"color: #555555\">:<\/span> singleValue{s} {}\n    <span style=\"color: #007788; font-weight: bold\">int<\/span> getValue() <span style=\"color: #006699; font-weight: bold\">const<\/span> {\n        <span style=\"color: #006699; font-weight: bold\">return<\/span> singleValue;\n    }\n <span style=\"color: #9999FF\">private:<\/span>\n    <span style=\"color: #007788; font-weight: bold\">int<\/span> singleValue{};\n};\n\n<span style=\"color: #006699; font-weight: bold\">template<\/span><span style=\"color: #555555\">&lt;&gt;<\/span>\n<span style=\"color: #006699; font-weight: bold\">struct<\/span> std<span style=\"color: #555555\">::<\/span>formatter<span style=\"color: #555555\">&lt;<\/span>SingleValue<span style=\"color: #555555\">&gt;<\/span> <span style=\"color: #555555\">:<\/span> std<span style=\"color: #555555\">::<\/span>formatter<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>\n  <span style=\"color: #006699; font-weight: bold\">auto<\/span> format(<span style=\"color: #006699; font-weight: bold\">const<\/span> SingleValue<span style=\"color: #555555\">&amp;<\/span> singleValue, std<span style=\"color: #555555\">::<\/span>format_context<span style=\"color: #555555\">&amp;<\/span> context) <span style=\"color: #006699; font-weight: bold\">const<\/span> {\n    <span style=\"color: #006699; font-weight: bold\">return<\/span> std<span style=\"color: #555555\">::<\/span>formatter<span style=\"color: #555555\">&lt;<\/span><span style=\"color: #007788; font-weight: bold\">int<\/span><span style=\"color: #555555\">&gt;::<\/span>format(singleValue.getValue(), context);\n  }\n};\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    SingleValue singleValue0;\n    SingleValue singleValue2020{<span style=\"color: #FF6600\">2020<\/span>};\n    SingleValue singleValue2023{<span style=\"color: #FF6600\">2023<\/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;{:*&lt;10}&quot;<\/span>, singleValue0) <span style=\"color: #555555\">&lt;&lt;<\/span> <span style=\"color: #CC3300\">&#39;\\n&#39;<\/span>;\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;{:*^10}&quot;<\/span>, singleValue2020) <span style=\"color: #555555\">&lt;&lt;<\/span> <span style=\"color: #CC3300\">&#39;\\n&#39;<\/span>;\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;{:*&gt;10}&quot;<\/span>, singleValue2023) <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> <span style=\"color: #CC3300\">&#39;\\n&#39;<\/span>;\n\n}\n<\/pre><\/div>\n\n\n\n<p>I derive <code>std::formatter&lt;SingleValue&gt;<\/code> from<code> std::formatter&lt;int&gt;<\/code> (line 1). Only the <code>format<\/code> function must be implemented. The output of this program is identical to the output of the previous program <code>formatSingleValueDelegation.cpp<\/code>.<\/p>\n\n\n\n<p>Delegating to a standard formatter or inheriting from one is a straightforward way to implement a user-defined formatter. This strategy only works for user-defined types having one value.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">What&#8217;s Next?<\/h2>\n\n\n\n<p>In my next blog, I will implement a formatter for a user-defined type having more than one value.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Additionally, to the basic types and std::string, you can also format user-defined types in C++20. So far, I have formatted basic types and std::string. Here are my previous posts: std::formatter enables it to format user-defined types. You have to specialize the class std::formatter for the user-defined type. In particular, you must implement the member functions [&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-9091","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\/9091","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=9091"}],"version-history":[{"count":26,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/9091\/revisions"}],"predecessor-version":[{"id":9126,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/9091\/revisions\/9126"}],"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=9091"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=9091"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=9091"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}