{"id":8139,"date":"2023-08-28T06:49:55","date_gmt":"2023-08-28T06:49:55","guid":{"rendered":"https:\/\/www.modernescpp.com\/?p=8139"},"modified":"2023-08-28T07:10:01","modified_gmt":"2023-08-28T07:10:01","slug":"c23-a-new-way-of-error-handling-with-stdexpected","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/c23-a-new-way-of-error-handling-with-stdexpected\/","title":{"rendered":"C++23: A New Way of Error Handling with std::expected"},"content":{"rendered":"\n<p>C++23 extends the interface of <code>std::optional<\/code> and gets the new data type <code>std::expected<\/code> for error handling.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2023\/08\/Cpp23-1-1030x579.png\" alt=\"\" class=\"wp-image-8141\" style=\"width:800px;height:450px\" width=\"800\" height=\"450\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2023\/08\/Cpp23-1-1030x579.png 1030w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2023\/08\/Cpp23-1-300x169.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2023\/08\/Cpp23-1-768x432.png 768w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2023\/08\/Cpp23-1-705x397.png 705w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2023\/08\/Cpp23-1.png 1280w\" sizes=\"auto, (max-width: 800px) 100vw, 800px\" \/><\/figure>\n\n\n\n<p>Before I dive into the extended monadic interface of<code> std::optional<\/code> in C++23, I want to introduce this C++17 type.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><code>std::optional<\/code><\/h2>\n\n\n\n<p><code>std::optional<\/code> is quite comfortable for calculations such as database queries that may have a result. This vocabulary type requires the header &lt;<code>optional<\/code>&gt;. <\/p>\n\n\n\n<p>The various constructors and the convenience function <code>std::make_optional<\/code> let you define an optional object <code>opt <\/code>with or without a value. <code>opt.emplace<\/code> will construct the contained value in-place and <code>opt.reset<\/code> will destroy the container value. You can explicitly ask a<code> std::optional<\/code> container if it has a value, or you can check it in a logical expression. <code>opt.value<\/code> returns the value, and <code>opt.value_or<\/code> returns the value or a default value. If <code>opt <\/code>has no contained value, the call <code>opt.value<\/code> will throw a <code>std::bad_optional_access<\/code> exception.<\/p>\n\n\n\n<p>Here is a short example using <code>std::optional<\/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\">\/\/ optional.cpp<\/span>\n\n<span style=\"color: #009999\">#include &lt;optional&gt;<\/span>\n<span style=\"color: #009999\">#include &lt;iostream&gt;<\/span>\n<span style=\"color: #009999\">#include &lt;vector&gt;<\/span>\n\nstd<span style=\"color: #555555\">::<\/span>optional<span style=\"color: #555555\">&lt;<\/span><span style=\"color: #007788; font-weight: bold\">int<\/span><span style=\"color: #555555\">&gt;<\/span> getFirst(<span style=\"color: #006699; font-weight: bold\">const<\/span> std<span style=\"color: #555555\">::<\/span>vector<span style=\"color: #555555\">&lt;<\/span><span style=\"color: #007788; font-weight: bold\">int<\/span><span style=\"color: #555555\">&gt;&amp;<\/span> vec){\n  <span style=\"color: #006699; font-weight: bold\">if<\/span> ( <span style=\"color: #555555\">!<\/span>vec.empty() ) <span style=\"color: #006699; font-weight: bold\">return<\/span> std<span style=\"color: #555555\">::<\/span>optional<span style=\"color: #555555\">&lt;<\/span><span style=\"color: #007788; font-weight: bold\">int<\/span><span style=\"color: #555555\">&gt;<\/span>(vec[<span style=\"color: #FF6600\">0<\/span>]);\n  <span style=\"color: #006699; font-weight: bold\">else<\/span> <span style=\"color: #006699; font-weight: bold\">return<\/span> std<span style=\"color: #555555\">::<\/span>optional<span style=\"color: #555555\">&lt;<\/span><span style=\"color: #007788; font-weight: bold\">int<\/span><span style=\"color: #555555\">&gt;<\/span>();\n}\n\n<span style=\"color: #007788; font-weight: bold\">int<\/span> main() {\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>vector<span style=\"color: #555555\">&lt;<\/span><span style=\"color: #007788; font-weight: bold\">int<\/span><span style=\"color: #555555\">&gt;<\/span> myVec{<span style=\"color: #FF6600\">1<\/span>, <span style=\"color: #FF6600\">2<\/span>, <span style=\"color: #FF6600\">3<\/span>};\n    std<span style=\"color: #555555\">::<\/span>vector<span style=\"color: #555555\">&lt;<\/span><span style=\"color: #007788; font-weight: bold\">int<\/span><span style=\"color: #555555\">&gt;<\/span> myEmptyVec;\n    \n    <span style=\"color: #006699; font-weight: bold\">auto<\/span> myInt<span style=\"color: #555555\">=<\/span> getFirst(myVec);\n    \n    <span style=\"color: #006699; font-weight: bold\">if<\/span> (myInt){\n        std<span style=\"color: #555555\">::<\/span>cout <span style=\"color: #555555\">&lt;&lt;<\/span> <span style=\"color: #CC3300\">&quot;*myInt: &quot;<\/span>  <span style=\"color: #555555\">&lt;&lt;<\/span> <span style=\"color: #555555\">*<\/span>myInt <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> <span style=\"color: #CC3300\">&quot;myInt.value(): &quot;<\/span> <span style=\"color: #555555\">&lt;&lt;<\/span> myInt.value() <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> <span style=\"color: #CC3300\">&quot;myInt.value_or(2017):&quot;<\/span> <span style=\"color: #555555\">&lt;&lt;<\/span> myInt.value_or(<span style=\"color: #FF6600\">2017<\/span>) <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    <span style=\"color: #006699; font-weight: bold\">auto<\/span> myEmptyInt<span style=\"color: #555555\">=<\/span> getFirst(myEmptyVec);\n    \n    <span style=\"color: #006699; font-weight: bold\">if<\/span> (<span style=\"color: #555555\">!<\/span>myEmptyInt){\n        std<span style=\"color: #555555\">::<\/span>cout <span style=\"color: #555555\">&lt;&lt;<\/span> <span style=\"color: #CC3300\">&quot;myEmptyInt.value_or(2017):&quot;<\/span> <span style=\"color: #555555\">&lt;&lt;<\/span> myEmptyInt.value_or(<span style=\"color: #FF6600\">2017<\/span>) <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>I use <code>std::optional <\/code>in the function <code>getFirst<\/code>.<code> getFirst<\/code> returns the first element if it exists. You get a <code>std::optional<\/code> object if not. The main function has two vectors. Both invoke <code>getFirst <\/code>and return a <code>std::optional <\/code>object. In the case of <code>myInt<\/code>, the object has a value; in the case of <code>myEmptyInt<\/code>, the object has no value. The program displays the value of <code>myInt <\/code>and <code>myEmptyInt<\/code>. <code>myInt.value_or(2017)<\/code> returns the value, but <code>myEmptyInt.value_or(2017) <\/code>returns the default value. <\/p>\n\n\n\n<p>Here is the output of the program.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full is-resized\"><img decoding=\"async\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2023\/08\/optional.png\" alt=\"\" class=\"wp-image-8144\" style=\"width:400px\" width=\"400\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2023\/08\/optional.png 446w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2023\/08\/optional-300x232.png 300w\" sizes=\"(max-width: 446px) 100vw, 446px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">The Monadic Extension of <code>std::optional<\/code><\/h2>\n\n\n\n<p>In C++23, <code>std::optional<\/code> is extended with monadic operations <code>opt.and_then<\/code>, <code>opt.transform<\/code>, and <code>opt.or_else. <\/code><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>opt.and_then<\/code> returns the result of the given function call if it exists or an empty <code>std::optional<\/code>.<\/li>\n\n\n\n<li><code>opt.transform<\/code> returns a <code>std::optional<\/code> containing its transformed value or an empty <code>std::optional<\/code>. <\/li>\n\n\n\n<li><code>opt.or_else<\/code> returns the<code> std::optional<\/code> if it contains a value or the result of the given function otherwise.<\/li>\n<\/ul>\n\n\n\n<p>These monadic operations enable the composition of operations on <code>std::optional<\/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\">\/\/ optionalMonadic.cpp<\/span>\n\n<span style=\"color: #009999\">#include &lt;iostream&gt;<\/span>\n<span style=\"color: #009999\">#include &lt;optional&gt;<\/span>\n<span style=\"color: #009999\">#include &lt;vector&gt;<\/span>\n<span style=\"color: #009999\">#include &lt;string&gt;<\/span>\n\nstd<span style=\"color: #555555\">::<\/span>optional<span style=\"color: #555555\">&lt;<\/span><span style=\"color: #007788; font-weight: bold\">int<\/span><span style=\"color: #555555\">&gt;<\/span> getInt(std<span style=\"color: #555555\">::<\/span>string arg) {\n    try {\n        <span style=\"color: #006699; font-weight: bold\">return<\/span> {std<span style=\"color: #555555\">::<\/span>stoi(arg)};\n    }\n    <span style=\"color: #006699; font-weight: bold\">catch<\/span> (...) {\n        <span style=\"color: #006699; font-weight: bold\">return<\/span> { };\n    }\n}\n\n \n<span style=\"color: #007788; font-weight: bold\">int<\/span> main() {\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>vector<span style=\"color: #555555\">&lt;<\/span>std<span style=\"color: #555555\">::<\/span>optional<span style=\"color: #555555\">&lt;<\/span>std<span style=\"color: #555555\">::<\/span>string<span style=\"color: #555555\">&gt;&gt;<\/span> strings <span style=\"color: #555555\">=<\/span> {<span style=\"color: #CC3300\">&quot;66&quot;<\/span>, <span style=\"color: #CC3300\">&quot;foo&quot;<\/span>, <span style=\"color: #CC3300\">&quot;-5&quot;<\/span>};\n\n    <span style=\"color: #006699; font-weight: bold\">for<\/span> (<span style=\"color: #006699; font-weight: bold\">auto<\/span> s<span style=\"color: #555555\">:<\/span> strings) {\n        <span style=\"color: #006699; font-weight: bold\">auto<\/span> res <span style=\"color: #555555\">=<\/span> s.and_then(getInt)\n                  .transform( [](<span style=\"color: #007788; font-weight: bold\">int<\/span> n) { <span style=\"color: #006699; font-weight: bold\">return<\/span> n <span style=\"color: #555555\">+<\/span> <span style=\"color: #FF6600\">100<\/span>;})\n                  .transform( [](<span style=\"color: #007788; font-weight: bold\">int<\/span> n) { <span style=\"color: #006699; font-weight: bold\">return<\/span> std<span style=\"color: #555555\">::<\/span>to_string(n); })\n                  .or_else([] { <span style=\"color: #006699; font-weight: bold\">return<\/span> std<span style=\"color: #555555\">::<\/span>optional{std<span style=\"color: #555555\">::<\/span>string(<span style=\"color: #CC3300\">&quot;Error&quot;<\/span>) }; });\n        std<span style=\"color: #555555\">::<\/span>cout <span style=\"color: #555555\">&lt;&lt;<\/span> <span style=\"color: #555555\">*<\/span>res <span style=\"color: #555555\">&lt;&lt;<\/span> <span style=\"color: #CC3300\">&#39; &#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 range-based for-loop iterates through the <code>std::vector&lt;std::optional&lt;std::string&gt;&gt;<\/code>. First, the function <code>getInt <\/code>converts each element to an integer, adds 100, converts it back to a string, and finally displays it. If the initial conversion to <code>int <\/code>fails, the string <code>Error <\/code>is returned and displayed.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"466\" height=\"153\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2023\/08\/optionalMonadic.png\" alt=\"\" class=\"wp-image-8149\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2023\/08\/optionalMonadic.png 466w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2023\/08\/optionalMonadic-300x98.png 300w\" sizes=\"auto, (max-width: 466px) 100vw, 466px\" \/><\/figure>\n\n\n\n<p><code>std::expected<\/code> already supports the monadic interface.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><code>std::expected<\/code><\/h2>\n\n\n\n<p><code>std::expected&lt;T, E&gt;<\/code> provides a way to store either of two values. An instance of <code>std::expected <\/code>always holds a value: either the expected value of type <code>T<\/code>, or the unexpected value of type <code>E<\/code>. This vocabulary type requires the header &lt;<code>expected<\/code>&gt;. Thanks to<code> std::expected<\/code>, you can implement functions that either return a value or an error. The stored value is allocated directly within the storage occupied by the expected object. No dynamic memory allocation takes place.<\/p>\n\n\n\n<p><code>std::expected<\/code> has a similar interface, such as <code>std::optional<\/code>. In contrast to <code>std::optional<\/code>, <code>std::exptected<\/code> can return an error message.<\/p>\n\n\n\n<p>The various constructors let you define an expected object <code>exp <\/code>with an expected value. <code>exp.emplace<\/code> will construct the contained value in-place. You can explicitly ask a <code>std::expected<\/code> container if it has a value, or you can check it in a logical expression. <code>exp.value<\/code> returns the expected value, and <code>exp.value_or<\/code> returns the expected value or a default value. If <code>exp <\/code>has an unexpected value, the call <code>exp.value<\/code> will throw a <code>std::bad_expected_access<\/code> exception.<\/p>\n\n\n\n<p><code>std::unexpected<\/code> represents the unexpected value stored in <code>std::expected<\/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\">\/\/ expected.cpp<\/span>\n\n<span style=\"color: #009999\">#include &lt;iostream&gt;<\/span>\n<span style=\"color: #009999\">#include &lt;expected&gt;<\/span>\n<span style=\"color: #009999\">#include &lt;vector&gt;<\/span>\n<span style=\"color: #009999\">#include &lt;string&gt;<\/span>\n\nstd<span style=\"color: #555555\">::<\/span>expected<span style=\"color: #555555\">&lt;<\/span><span style=\"color: #007788; font-weight: bold\">int<\/span>, std<span style=\"color: #555555\">::<\/span>string<span style=\"color: #555555\">&gt;<\/span> getInt(std<span style=\"color: #555555\">::<\/span>string arg) {\n    try {\n        <span style=\"color: #006699; font-weight: bold\">return<\/span> std<span style=\"color: #555555\">::<\/span>stoi(arg);\n    }\n    <span style=\"color: #006699; font-weight: bold\">catch<\/span> (...) {\n        <span style=\"color: #006699; font-weight: bold\">return<\/span> std<span style=\"color: #555555\">::<\/span>unexpected{std<span style=\"color: #555555\">::<\/span>string(arg <span style=\"color: #555555\">+<\/span> <span style=\"color: #CC3300\">&quot;: Error&quot;<\/span>)};\n    }\n}\n\n \n<span style=\"color: #007788; font-weight: bold\">int<\/span> main() {\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>vector<span style=\"color: #555555\">&lt;<\/span>std<span style=\"color: #555555\">::<\/span>string<span style=\"color: #555555\">&gt;<\/span> strings <span style=\"color: #555555\">=<\/span> {<span style=\"color: #CC3300\">&quot;66&quot;<\/span>, <span style=\"color: #CC3300\">&quot;foo&quot;<\/span>, <span style=\"color: #CC3300\">&quot;-5&quot;<\/span>};\n\n    <span style=\"color: #006699; font-weight: bold\">for<\/span> (<span style=\"color: #006699; font-weight: bold\">auto<\/span> s<span style=\"color: #555555\">:<\/span> strings) {                                 <span style=\"color: #0099FF; font-style: italic\">\/\/ (1)<\/span>\n        <span style=\"color: #006699; font-weight: bold\">auto<\/span> res <span style=\"color: #555555\">=<\/span> getInt(s);\n        <span style=\"color: #006699; font-weight: bold\">if<\/span> (res) {\n            std<span style=\"color: #555555\">::<\/span>cout <span style=\"color: #555555\">&lt;&lt;<\/span> res.value() <span style=\"color: #555555\">&lt;&lt;<\/span> <span style=\"color: #CC3300\">&#39; &#39;<\/span>;                <span style=\"color: #0099FF; font-style: italic\">\/\/ (3)<\/span>\n        }\n        <span style=\"color: #006699; font-weight: bold\">else<\/span> {\n            std<span style=\"color: #555555\">::<\/span>cout <span style=\"color: #555555\">&lt;&lt;<\/span> res.error() <span style=\"color: #555555\">&lt;&lt;<\/span> <span style=\"color: #CC3300\">&#39; &#39;<\/span>;                <span style=\"color: #0099FF; font-style: italic\">\/\/ (4)<\/span>\n        }\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    <span style=\"color: #006699; font-weight: bold\">for<\/span> (<span style=\"color: #006699; font-weight: bold\">auto<\/span> s<span style=\"color: #555555\">:<\/span> strings) {                                 <span style=\"color: #0099FF; font-style: italic\">\/\/ (2)<\/span>\n        <span style=\"color: #006699; font-weight: bold\">auto<\/span> res <span style=\"color: #555555\">=<\/span> getInt(s);\n        std<span style=\"color: #555555\">::<\/span>cout <span style=\"color: #555555\">&lt;&lt;<\/span> res.value_or(<span style=\"color: #FF6600\">2023<\/span>) <span style=\"color: #555555\">&lt;&lt;<\/span> <span style=\"color: #CC3300\">&#39; &#39;<\/span>;             <span style=\"color: #0099FF; font-style: italic\">\/\/ (5)<\/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 function <code>getInt <\/code>converts each string to an integer and returns a <code>std::expected&lt;int, std::string&gt;<\/code>. <code>int <\/code>represents the expected, and <code>std::string <\/code>the unexpected value. The two range-based for-loops (lines 1 and 2) iterate through the<code> std::vector&lt;std::string&gt;<\/code>. In the first range-based for-loop (line 1), the expected (line 3) or the unexpected value (line 4) is displayed. In the second range-based for-loop (line 2), the expected or the default value 2023 (line 5) is displayed.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"466\" height=\"191\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2023\/08\/expected.png\" alt=\"\" class=\"wp-image-8159\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2023\/08\/expected.png 466w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2023\/08\/expected-300x123.png 300w\" sizes=\"auto, (max-width: 466px) 100vw, 466px\" \/><\/figure>\n\n\n\n<p><code>std::expected<\/code> supports monadic operations for convenient function composition: <code>exp.and_then<\/code>, <code>exp.transform, exp.or_else<\/code>, and<code> exp.transform_error<\/code>. <\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>e<code>xp.and_then<\/code> returns the result of the given function call if it exists or an empty <code>std::expected<\/code>. <\/li>\n\n\n\n<li><code>exp.transform<\/code> returns a<code> std::expected<\/code> containing its transformed value or an empty <code>std::exptec<\/code>ted.<\/li>\n\n\n\n<li><code>exp.or_else<\/code> returns the <code>std::expecte<\/code>d if it contains a value or the result of the given function otherwise. \u00a0<\/li>\n\n\n\n<li><code>exp.transform_error<\/code> returns the std::<code>expected<\/code> if it contains an expected value. Otherwise, it returns a <code>std::expected<\/code> that contains a transformed unexpected value.<\/li>\n<\/ul>\n\n\n\n<p>The following program is based on the previous program <code>optionalMonadic.cpp<\/code>. Essentially, the type <code>std::optional<\/code> is replaced with <code>std::expected<\/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\">\/\/ expectedMonadic.cpp<\/span>\n\n<span style=\"color: #009999\">#include &lt;iostream&gt;<\/span>\n<span style=\"color: #009999\">#include &lt;expected&gt;<\/span>\n<span style=\"color: #009999\">#include &lt;vector&gt;<\/span>\n<span style=\"color: #009999\">#include &lt;string&gt;<\/span>\n\n\nstd<span style=\"color: #555555\">::<\/span>expected<span style=\"color: #555555\">&lt;<\/span><span style=\"color: #007788; font-weight: bold\">int<\/span>, std<span style=\"color: #555555\">::<\/span>string<span style=\"color: #555555\">&gt;<\/span> getInt(std<span style=\"color: #555555\">::<\/span>string arg) {\n    try {\n        <span style=\"color: #006699; font-weight: bold\">return<\/span> std<span style=\"color: #555555\">::<\/span>stoi(arg);\n    }\n    <span style=\"color: #006699; font-weight: bold\">catch<\/span> (...) {\n        <span style=\"color: #006699; font-weight: bold\">return<\/span> std<span style=\"color: #555555\">::<\/span>unexpected{std<span style=\"color: #555555\">::<\/span>string(arg <span style=\"color: #555555\">+<\/span> <span style=\"color: #CC3300\">&quot;: Error&quot;<\/span>)};\n    }\n}\n \n<span style=\"color: #007788; font-weight: bold\">int<\/span> main() {\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>vector<span style=\"color: #555555\">&lt;<\/span>std<span style=\"color: #555555\">::<\/span>string<span style=\"color: #555555\">&gt;<\/span> strings <span style=\"color: #555555\">=<\/span> {<span style=\"color: #CC3300\">&quot;66&quot;<\/span>, <span style=\"color: #CC3300\">&quot;foo&quot;<\/span>, <span style=\"color: #CC3300\">&quot;-5&quot;<\/span>};\n\n    <span style=\"color: #006699; font-weight: bold\">for<\/span> (<span style=\"color: #006699; font-weight: bold\">auto<\/span> s<span style=\"color: #555555\">:<\/span> strings) {\n        <span style=\"color: #006699; font-weight: bold\">auto<\/span> res <span style=\"color: #555555\">=<\/span> getInt(s)\n                   .transform( [](<span style=\"color: #007788; font-weight: bold\">int<\/span> n) { <span style=\"color: #006699; font-weight: bold\">return<\/span> n <span style=\"color: #555555\">+<\/span> <span style=\"color: #FF6600\">100<\/span>; })\n                   .transform( [](<span style=\"color: #007788; font-weight: bold\">int<\/span> n) { <span style=\"color: #006699; font-weight: bold\">return<\/span> std<span style=\"color: #555555\">::<\/span>to_string(n); });\n        std<span style=\"color: #555555\">::<\/span>cout <span style=\"color: #555555\">&lt;&lt;<\/span> <span style=\"color: #555555\">*<\/span>res <span style=\"color: #555555\">&lt;&lt;<\/span> <span style=\"color: #CC3300\">&#39; &#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 range-based for-loop iterates through the <code>std::vector&lt;std::string&gt;<\/code>. First, the function <code>getInt <\/code>converts each string to an integer, adds <code>100<\/code>, converts it back to a string, and finally displays it. If the initial conversion to <code>int <\/code>fails, the string <code>arg + \": Error\"<\/code> is returned and displayed. &nbsp; &nbsp;<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"466\" height=\"153\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2023\/08\/expectedMonadic.png\" alt=\"\" class=\"wp-image-8154\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2023\/08\/expectedMonadic.png 466w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2023\/08\/expectedMonadic-300x98.png 300w\" sizes=\"auto, (max-width: 466px) 100vw, 466px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">What&#8217;s Next? <\/h2>\n\n\n\n<p>The four associative containers <code>std::flat_map<\/code>, <code>std::flat_multimap<\/code>, <code>std::flat_set<\/code>, and <code>std::flat_multiset<\/code> in C++23 are a drop-in replacement for the ordered associative containers <code>std::map<\/code>,<code> std::multimap<\/code>, <code>std::set<\/code>, and <code>std::multiset<\/code>. We have them for one reason in C++23: performance. <\/p>\n","protected":false},"excerpt":{"rendered":"<p>C++23 extends the interface of std::optional and gets the new data type std::expected for error handling. Before I dive into the extended monadic interface of std::optional in C++23, I want to introduce this C++17 type. std::optional std::optional is quite comfortable for calculations such as database queries that may have a result. This vocabulary type requires [&hellip;]<\/p>\n","protected":false},"author":21,"featured_media":8141,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[378],"tags":[478],"class_list":["post-8139","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-c-23","tag-error-handling"],"_links":{"self":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/8139","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=8139"}],"version-history":[{"count":24,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/8139\/revisions"}],"predecessor-version":[{"id":8170,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/8139\/revisions\/8170"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media\/8141"}],"wp:attachment":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media?parent=8139"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=8139"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=8139"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}