{"id":4529,"date":"2022-08-17T21:53:31","date_gmt":"2022-08-17T19:53:31","guid":{"rendered":"https:\/\/mariusbancila.ro\/blog\/?p=4529"},"modified":"2022-08-17T21:53:31","modified_gmt":"2022-08-17T19:53:31","slug":"using-the-cpp23-expected-type","status":"publish","type":"post","link":"https:\/\/mariusbancila.ro\/blog\/2022\/08\/17\/using-the-cpp23-expected-type\/","title":{"rendered":"Using the C++23 std::expected type"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">The C++23 standard will feature a new utility type called <code>std::expected<\/code>. This type either contains an expected value, or an unexpected one, typically providing information about the reason something failed (and the expected value could not be returned). This feature is, at this time, <a href=\"https:\/\/en.cppreference.com\/w\/cpp\/compiler_support\/23\" target=\"_blank\" rel=\"noopener\">supported<\/a> in GCC 12 and MSVC 19.33 (Visual Studio 2022 17.3). In this article, we&#8217;ll see what <code>std::expected<\/code> is and how it can be used.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/mariusbancila.ro\/blog\/wp-content\/uploads\/2022\/08\/unexpectederror.png\"><img loading=\"lazy\" decoding=\"async\" width=\"512\" height=\"512\" src=\"https:\/\/mariusbancila.ro\/blog\/wp-content\/uploads\/2022\/08\/unexpectederror.png\" alt=\"\" class=\"wp-image-4538\" srcset=\"https:\/\/mariusbancila.ro\/blog\/wp-content\/uploads\/2022\/08\/unexpectederror.png 512w, https:\/\/mariusbancila.ro\/blog\/wp-content\/uploads\/2022\/08\/unexpectederror-300x300.png 300w, https:\/\/mariusbancila.ro\/blog\/wp-content\/uploads\/2022\/08\/unexpectederror-150x150.png 150w\" sizes=\"auto, (max-width: 512px) 100vw, 512px\" \/><\/a><\/figure>\n\n\n\n<!--more-->\n\n\n\n<h2 class=\"wp-block-heading\">Why do we need std::expected?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Suppose you have to write a function that returns some data. It has to perform one or more operations that may fail. This function needs to return the data, but also needs to indicate failure and the cause for the failure. There are different ways to implement this. <\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Alternative 1: status code + reference parameter<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">One alternative is to return a status code indicating success or the reason of failure. Additionally, the actual returned data is a parameter passed by reference.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">enum class Status\n{\n   Ok,\n   AccessDenied,\n   DataSourceError,\n   DataError,\n};\n\nbool HasAcccess() { return true; }\nint OpenConnection() { return 0; }\nint Fetch() { return 0; }\n\nStatus ReadData(std::vector&lt;int>&amp; data)\n{\n   if (!HasAcccess())\n      return Status::AccessDenied;\n\n   if (OpenConnection() != 0)\n      return Status::DataSourceError;\n\n   if (Fetch() != 0)\n      return Status::DataError;\n\n   data.push_back(42);\n\n   return Status::Ok;\n}<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This is how it  can be used:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">void print_value(int const v)\n{\n   std::cout &lt;&lt; v &lt;&lt; '\\n';\n}\n\nint main()\n{\n   std::vector&lt;int> data;\n   Status result = ReadData(data);\n   if (result == Status::Ok)\n   {\n      std::ranges::for_each(data, print_value);\n   }\n   else\n   {\n      std::cout &lt;&lt; std::format(\"Error code: {}\\n\", (int)result);\n   }\n}<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Alternative 2: using exceptions<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Another alternative is to return the actual data but in case of failure throw an exception.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">struct status_exception : public std::exception\n{\n   status_exception(Status status) : std::exception(), status_(status) {}\n\n   status_exception(Status status, char const* const message) : std::exception(message), status_(status) {}\n\n   Status status() const { return status_; }\n\nprivate:\n   Status status_;\n};\n\nstd::vector&lt;int> ReadData()\n{\n   if (!HasAcccess())\n      throw status_exception(Status::AccessDenied);\n\n   if (OpenConnection() != 0)\n      throw status_exception(Status::DataSourceError);\n\n   if (Fetch() != 0)\n      throw status_exception(Status::DataError);\n\n   std::vector&lt;int> data;\n\n   data.push_back(42);\n\n   return data;\n}<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This time, we need to try-catch the call:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">int main()\n{\n   try\n   {\n      auto data = ReadData();\n      std::ranges::for_each(data, print_value);\n   }\n   catch (status_exception const&amp; e)\n   {\n      std::cout &lt;&lt; std::format(\"Error code: {}\\n\", (int)e.status());\n   }      \n}<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Choosing between one of these could be a personal choice or may depend on imposed restrictions. For instance, there could be a no-exceptions requirement, in which case the 2nd alternative cannot be used.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Alternative 3: using std::variant<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Another possible options, in C++17, is to use <code>std::variant<\/code>. In this case, our function could looks as follows:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">std::variant&lt;std::vector&lt;int>, Status> ReadData()\n{\n   if (!HasAcccess())\n      return { Status::AccessDenied };\n\n   if (OpenConnection() != 0)\n      return {Status::DataSourceError};\n\n   if (Fetch() != 0)\n      return {Status::DataError};\n\n   std::vector&lt;int> data;\n\n   data.push_back(42);\n\n   return data;\n}<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">However, when it comes to using it, it gets nasty. We need to visit each possible alternative of the variant type and the syntax to do so is horrendous.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">int main()\n{\n   auto result = ReadData();\n   std::visit([](auto&amp; arg) {\n      using T = std::decay_t&lt;decltype(arg)>;\n\n      if constexpr (std::is_same_v&lt;T, std::vector&lt;int>>)\n      {\n         std::ranges::for_each(arg, print_value);\n      }\n      else if constexpr (std::is_same_v&lt;T, Status>)\n      {\n         std::cout &lt;&lt; std::format(\"Error code: {}\\n\", (int)arg);\n      }\n   }, result);\n}<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">In my opinion, <code>std::variant<\/code> is difficult to use, and I don&#8217;t like making use of it.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Note<\/strong>: you can read more about <code>std::variant<\/code> in this article: <a href=\"https:\/\/bitbashing.io\/std-visit.html\" target=\"_blank\" rel=\"noopener\">std::visit is everything wrong with modern C++<\/a>.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Alternative 4: using std::optional<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">The <code>std::optional<\/code> type may contain or may not contain a value. This can be used when returning no data is a valid option for a function that normally would return a value. Like in our case:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">std::optional&lt;std::vector&lt;int>> ReadData()\n{\n   if (!HasAcccess()) return {};\n\n   if (OpenConnection() != 0) return {};\n\n   if (Fetch() != 0) return {};\n\n   std::vector&lt;int> data;\n\n   data.push_back(42);\n\n   return data;\n}<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">We can use this as follows:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">int main()\n{\n   auto result = ReadData();\n   if (result)\n   {\n      std::ranges::for_each(result.value(), print_value);\n   }\n   else\n   {\n      std::cout &lt;&lt; \"No data\\n\";\n   }\n}<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The std::optional type has several members for checking and accessing the value, including:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><code>has_value()<\/code> (e.g. <code>if(result.has_value())<\/code>) checks whether the object contains a value<\/li><li><code>operator bool<\/code> (e.g. <code>if(result)<\/code>) performs the same check<\/li><li><code>value()<\/code> (e.g. <code>result.value()<\/code>) returns the contained value or throws <code>std::bad_optional_access<\/code> if the object does not contain a value<\/li><li><code>value_or()<\/code> (e.g. <code>result.value_or(...)<\/code>) returns the contained value or the supplied one if the object does not contain any value<\/li><li><code>operator-&gt;<\/code> and <code>operator*<\/code> (e.g. <code>*result<\/code>) access the contained value but have undefined behavior if the object does not contain any value<\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">The problem with this particular implementation of <code>ReadData<\/code> is that we didn&#8217;t get the reason for the failure back. To do so, we would either need to introduce a function parameter (passed by reference) or throw an exception (like with the second alternative presented earlier).<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Enter std::expected<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">In C++23, we get this new utility type, <code>std::expected&lt;T, E><\/code>, in the new <code>&lt;expected><\/code> header. This is supposed to be used for functions that return a value but may encounter some errors in which case they may return something else, such as information about the error. In a way, <code>std::expected<\/code> is a combination of <code>std::variant<\/code> and <code>std::optional<\/code>. On one hand, it&#8217;s a discriminated union, it either hold a <code>T<\/code> (the expected type) or an <code>E<\/code> (the unexpected type). This is at least, logically; but more of this, shortly. On the other hand, it was an interface similar to <code>std::optional&lt;T><\/code>:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><code>has_value()<\/code> (e.g. <code>if(result.has_value())<\/code>) returns <code>true<\/code> if the object contains the expected value (not the unexpected one)<\/li><li><code>operator bool<\/code> (e.g. <code>if(result)<\/code>) same as <code>has_value<\/code><\/li><li><code>value()<\/code> (e.g. <code>result.value()<\/code>) returns the expected value if the object contains one or throws <code>std::bad_expected_access&lt;E><\/code>, an exception type that contains the unexpected value stored by the <code>std::expected&lt;T, E><\/code> object<\/li><li><code>value_or()<\/code> (e.g. <code>result.value_or(...)<\/code>) returns the expected value if the object contains one or, otherwise, the supplied value<\/li><li><code>error()<\/code> returns the unexpected value contained by the <code>std::expected&lt;T, E><\/code> object<\/li><li><code>operator-><\/code> and <code>operator*<\/code> access the expected value, if the object contains one; otherwise, the behavior is undefined<\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Let&#8217;s see how the <code>ReadData<\/code> function may look when using <code>std::expected&lt;T, E&gt;<\/code> for the return type:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">std::expected&lt;std::vector&lt;int>, Status> ReadData()\n{\n   if (!HasAcccess())\n      return std::unexpected&lt;Status> { Status::AccessDenied };\n\n   if (OpenConnection() != 0)\n      return std::unexpected&lt;Status> {Status::DataSourceError};\n\n   if (Fetch() != 0)\n      return std::unexpected&lt;Status> {Status::DataError};\n\n   std::vector&lt;int> data;\n\n   data.push_back(42);\n\n   return data;\n}<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This implementation can be used as follows:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">int main()\n{\n   auto result = ReadData();\n   if (result)\n   {\n      std::ranges::for_each(result.value(), print_value);\n   }\n   else\n   {\n      std::cout &lt;&lt; std::format(\"Error code: {}\\n\", (int)result.error());\n   }\n}<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">In this implementation, when an error occurs, an <code>std::unexpected&lt;Status><\/code> value is return. This <code>std::unexpected<\/code> is a class template that acts as a container for an unexpected value of type <code>E<\/code>. The <code>std::expected&lt;T, E><\/code> models a discriminated union of types <code>T<\/code> and <code>std::unexpected&lt;E><\/code>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In the previous example, the different functions called by <code>ReadData<\/code> had different ways of indicating success (and returning data). When you have an algorithm, or routine that is made of smaller parts, and each part is a function that returns the same <code>std::expected<\/code> instantiation, the calls could be easily chained. Here is an example. Let&#8217;s consider a function that builds a user&#8217;s avatar, adding a frame, badge, and text to an existing image. For this, let&#8217;s assume the following stubs:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">struct avatar\n{\n};\n\nenum class error_code\n{\n   ok,\n   error,\n};\n\nusing avatar_result = std::expected&lt;avatar, error_code>;\n\navatar_result add_frame(avatar const&amp; a) { return a; \/* std::unexpected&lt;error_code>(error_code::error); *\/ }\navatar_result add_badge(avatar const&amp; a) { return a; \/* std::unexpected&lt;error_code>(error_code::error); *\/ }\navatar_result add_text(avatar const&amp; a)  { return a; \/* std::unexpected&lt;error_code>(error_code::error); *\/ }<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Using these, we can write the following <code>make_avatar<\/code> function:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">avatar_result make_avatar(avatar const&amp; a, bool const with_frame, bool const with_badge, bool const with_text)\n{\n   avatar_result result = a;\n\n   if (with_frame)\n   {\n      result = add_frame(*result);\n      if (!result)\n         return result;\n   }\n\n   if (with_badge)\n   {\n      result = add_badge(*result);\n      if (!result)\n         return result;\n   }\n\n   if (with_text)\n   {\n      result = add_text(*result);\n      if (!result)\n         return result;\n   }\n\n   return result;\n}<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Each step is handled in the same manner and the code is very simple. This <code>make_avatar<\/code> function can be used as follows:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">int main()\n{\n   avatar a;\n\n   auto result = make_avatar(a, true, true, false);\n   \n   if (result)\n   {\n      std::cout &lt;&lt; \"success\\n\";\n   }\n   else\n   {\n      std::cout &lt;&lt; \"Error: \" &lt;&lt; (int)result.error() &lt;&lt; '\\n';\n   }\n}<\/pre>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">References<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Support for <code>std::expected<\/code> is new and there isn&#8217;t a lot of documentation about it. But if you want to learn more, check the following:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>\ud83e\uddfe <a href=\"https:\/\/www.open-std.org\/jtc1\/sc22\/wg21\/docs\/papers\/2022\/p0323r12.html\" target=\"_blank\" rel=\"noopener\">P0323R12 std::expected<\/a><\/li><li>\ud83e\uddfe <a href=\"https:\/\/github.com\/TartanLlama\/expected\" target=\"_blank\" rel=\"noopener\">expected<\/a><\/li><li>\ud83c\udfa6 <a href=\"https:\/\/www.youtube.com\/watch?v=PH4WBuE1BHI\" target=\"_blank\" rel=\"noopener\">expect the expected<\/a><\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n","protected":false},"excerpt":{"rendered":"<p>The C++23 standard will feature a new utility type called std::expected. This type either contains an expected value, or an unexpected one, typically providing information about the reason something failed (and the expected value could not be returned). This feature is, at this time, supported in GCC 12 and MSVC 19.33 (Visual Studio 2022 17.3). &#8230; <a title=\"Using the C++23 std::expected type\" class=\"read-more\" href=\"https:\/\/mariusbancila.ro\/blog\/2022\/08\/17\/using-the-cpp23-expected-type\/\" aria-label=\"Read more about Using the C++23 std::expected type\">Read more<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_uag_custom_page_level_css":"","advgb_blocks_editor_width":"","advgb_blocks_columns_visual_guide":"","_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_feature_clip_id":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2},"jetpack_post_was_ever_published":false},"categories":[7],"tags":[451,632,642],"class_list":["post-4529","post","type-post","status-publish","format-standard","hentry","category-c","tag-c","tag-c23","tag-stdexpected"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.1.1 - aioseo.com -->\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Marius Bancila\"\/>\n\t<meta name=\"keywords\" content=\"c++,c++23,std::expected\" \/>\n\t<link rel=\"canonical\" href=\"https:\/\/mariusbancila.ro\/blog\/2022\/08\/17\/using-the-cpp23-expected-type\/\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.1.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"en_US\" \/>\n\t\t<meta property=\"og:site_name\" content=\"Marius Bancila&#039;s Blog | About code. Mostly on C++\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"Using the C++23 std::expected type\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/mariusbancila.ro\/blog\/2022\/08\/17\/using-the-cpp23-expected-type\/\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2022-08-17T19:53:31+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2022-08-17T19:53:31+00:00\" \/>\n\t\t<meta name=\"twitter:card\" content=\"summary\" \/>\n\t\t<meta name=\"twitter:title\" content=\"Using the C++23 std::expected type\" \/>\n\t\t<script type=\"application\/ld+json\" class=\"aioseo-schema\">\n\t\t\t{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2022\\\/08\\\/17\\\/using-the-cpp23-expected-type\\\/#article\",\"name\":\"Using the C++23 std::expected type\",\"headline\":\"Using the C++23 std::expected type\",\"author\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/author\\\/admin\\\/#author\"},\"publisher\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/#organization\"},\"image\":{\"@type\":\"ImageObject\",\"url\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/wp-content\\\/uploads\\\/2022\\\/08\\\/unexpectederror.png\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2022\\\/08\\\/17\\\/using-the-cpp23-expected-type\\\/#articleImage\",\"width\":512,\"height\":512},\"datePublished\":\"2022-08-17T21:53:31+02:00\",\"dateModified\":\"2022-08-17T21:53:31+02:00\",\"inLanguage\":\"en-US\",\"commentCount\":3,\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2022\\\/08\\\/17\\\/using-the-cpp23-expected-type\\\/#webpage\"},\"isPartOf\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2022\\\/08\\\/17\\\/using-the-cpp23-expected-type\\\/#webpage\"},\"articleSection\":\"C++, C++, C++23, std::expected\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2022\\\/08\\\/17\\\/using-the-cpp23-expected-type\\\/#breadcrumblist\",\"itemListElement\":[{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog#listItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/#listItem\",\"name\":\"IT\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/#listItem\",\"position\":2,\"name\":\"IT\",\"item\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/#listItem\",\"name\":\"Software\"},\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog#listItem\",\"name\":\"Home\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/#listItem\",\"position\":3,\"name\":\"Software\",\"item\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/c\\\/#listItem\",\"name\":\"C++\"},\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/#listItem\",\"name\":\"IT\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/c\\\/#listItem\",\"position\":4,\"name\":\"C++\",\"item\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/c\\\/\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2022\\\/08\\\/17\\\/using-the-cpp23-expected-type\\\/#listItem\",\"name\":\"Using the C++23 std::expected type\"},\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/#listItem\",\"name\":\"Software\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2022\\\/08\\\/17\\\/using-the-cpp23-expected-type\\\/#listItem\",\"position\":5,\"name\":\"Using the C++23 std::expected type\",\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/c\\\/#listItem\",\"name\":\"C++\"}}]},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/#organization\",\"name\":\"Marius Bancila's Blog\",\"description\":\"About code. Mostly on C++\",\"url\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/author\\\/admin\\\/#author\",\"url\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/author\\\/admin\\\/\",\"name\":\"Marius Bancila\",\"image\":{\"@type\":\"ImageObject\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2022\\\/08\\\/17\\\/using-the-cpp23-expected-type\\\/#authorImage\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/a84dd2831d955c38355ddea55df4df260809b88f36408bc14fd4eab8f7f131c9?s=96&d=mm&r=g\",\"width\":96,\"height\":96,\"caption\":\"Marius Bancila\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2022\\\/08\\\/17\\\/using-the-cpp23-expected-type\\\/#webpage\",\"url\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2022\\\/08\\\/17\\\/using-the-cpp23-expected-type\\\/\",\"name\":\"Using the C++23 std::expected type\",\"inLanguage\":\"en-US\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/#website\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2022\\\/08\\\/17\\\/using-the-cpp23-expected-type\\\/#breadcrumblist\"},\"author\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/author\\\/admin\\\/#author\"},\"creator\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/author\\\/admin\\\/#author\"},\"datePublished\":\"2022-08-17T21:53:31+02:00\",\"dateModified\":\"2022-08-17T21:53:31+02:00\"},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/\",\"name\":\"Marius Bancila's Blog\",\"description\":\"About code. Mostly on C++\",\"inLanguage\":\"en-US\",\"publisher\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/#organization\"}}]}\n\t\t<\/script>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"Using the C++23 std::expected type","description":"","canonical_url":"https:\/\/mariusbancila.ro\/blog\/2022\/08\/17\/using-the-cpp23-expected-type\/","robots":"max-image-preview:large","keywords":"c++,c++23,std::expected","webmasterTools":{"miscellaneous":""},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/mariusbancila.ro\/blog\/2022\/08\/17\/using-the-cpp23-expected-type\/#article","name":"Using the C++23 std::expected type","headline":"Using the C++23 std::expected type","author":{"@id":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/#author"},"publisher":{"@id":"https:\/\/mariusbancila.ro\/blog\/#organization"},"image":{"@type":"ImageObject","url":"https:\/\/mariusbancila.ro\/blog\/wp-content\/uploads\/2022\/08\/unexpectederror.png","@id":"https:\/\/mariusbancila.ro\/blog\/2022\/08\/17\/using-the-cpp23-expected-type\/#articleImage","width":512,"height":512},"datePublished":"2022-08-17T21:53:31+02:00","dateModified":"2022-08-17T21:53:31+02:00","inLanguage":"en-US","commentCount":3,"mainEntityOfPage":{"@id":"https:\/\/mariusbancila.ro\/blog\/2022\/08\/17\/using-the-cpp23-expected-type\/#webpage"},"isPartOf":{"@id":"https:\/\/mariusbancila.ro\/blog\/2022\/08\/17\/using-the-cpp23-expected-type\/#webpage"},"articleSection":"C++, C++, C++23, std::expected"},{"@type":"BreadcrumbList","@id":"https:\/\/mariusbancila.ro\/blog\/2022\/08\/17\/using-the-cpp23-expected-type\/#breadcrumblist","itemListElement":[{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog#listItem","position":1,"name":"Home","item":"https:\/\/mariusbancila.ro\/blog","nextItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/#listItem","name":"IT"}},{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/#listItem","position":2,"name":"IT","item":"https:\/\/mariusbancila.ro\/blog\/category\/it\/","nextItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/#listItem","name":"Software"},"previousItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog#listItem","name":"Home"}},{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/#listItem","position":3,"name":"Software","item":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/","nextItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/c\/#listItem","name":"C++"},"previousItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/#listItem","name":"IT"}},{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/c\/#listItem","position":4,"name":"C++","item":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/c\/","nextItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/2022\/08\/17\/using-the-cpp23-expected-type\/#listItem","name":"Using the C++23 std::expected type"},"previousItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/#listItem","name":"Software"}},{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/2022\/08\/17\/using-the-cpp23-expected-type\/#listItem","position":5,"name":"Using the C++23 std::expected type","previousItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/c\/#listItem","name":"C++"}}]},{"@type":"Organization","@id":"https:\/\/mariusbancila.ro\/blog\/#organization","name":"Marius Bancila's Blog","description":"About code. Mostly on C++","url":"https:\/\/mariusbancila.ro\/blog\/"},{"@type":"Person","@id":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/#author","url":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/","name":"Marius Bancila","image":{"@type":"ImageObject","@id":"https:\/\/mariusbancila.ro\/blog\/2022\/08\/17\/using-the-cpp23-expected-type\/#authorImage","url":"https:\/\/secure.gravatar.com\/avatar\/a84dd2831d955c38355ddea55df4df260809b88f36408bc14fd4eab8f7f131c9?s=96&d=mm&r=g","width":96,"height":96,"caption":"Marius Bancila"}},{"@type":"WebPage","@id":"https:\/\/mariusbancila.ro\/blog\/2022\/08\/17\/using-the-cpp23-expected-type\/#webpage","url":"https:\/\/mariusbancila.ro\/blog\/2022\/08\/17\/using-the-cpp23-expected-type\/","name":"Using the C++23 std::expected type","inLanguage":"en-US","isPartOf":{"@id":"https:\/\/mariusbancila.ro\/blog\/#website"},"breadcrumb":{"@id":"https:\/\/mariusbancila.ro\/blog\/2022\/08\/17\/using-the-cpp23-expected-type\/#breadcrumblist"},"author":{"@id":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/#author"},"creator":{"@id":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/#author"},"datePublished":"2022-08-17T21:53:31+02:00","dateModified":"2022-08-17T21:53:31+02:00"},{"@type":"WebSite","@id":"https:\/\/mariusbancila.ro\/blog\/#website","url":"https:\/\/mariusbancila.ro\/blog\/","name":"Marius Bancila's Blog","description":"About code. Mostly on C++","inLanguage":"en-US","publisher":{"@id":"https:\/\/mariusbancila.ro\/blog\/#organization"}}]},"og:locale":"en_US","og:site_name":"Marius Bancila's Blog | About code. Mostly on C++","og:type":"article","og:title":"Using the C++23 std::expected type","og:url":"https:\/\/mariusbancila.ro\/blog\/2022\/08\/17\/using-the-cpp23-expected-type\/","article:published_time":"2022-08-17T19:53:31+00:00","article:modified_time":"2022-08-17T19:53:31+00:00","twitter:card":"summary","twitter:title":"Using the C++23 std::expected type"},"aioseo_meta_data":{"post_id":"4529","title":null,"description":null,"keywords":[],"keyphrases":{"focus":{"keyphrase":"","score":0,"analysis":{"keyphraseInTitle":{"score":0,"maxScore":9,"error":1}}},"additional":[]},"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":"","og_custom_url":null,"og_article_section":null,"og_article_tags":[],"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":{"id":"aioseo-article-6369651300385","slug":"article","graphName":"Article","label":"Article","properties":{"type":"BlogPosting","name":"#post_title","headline":"#post_title","description":"#post_excerpt","image":"","keywords":"","author":{"name":"#author_name","url":"#author_url"},"dates":{"include":true,"datePublished":"","dateModified":""}}},"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"Article","isEnabled":true},"graphs":[]},"schema_type":"default","schema_type_options":"{\"article\":{\"articleType\":\"BlogPosting\"},\"course\":{\"name\":\"\",\"description\":\"\",\"provider\":\"\"},\"faq\":{\"pages\":[]},\"product\":{\"reviews\":[]},\"recipe\":{\"ingredients\":[],\"instructions\":[],\"keywords\":[]},\"software\":{\"reviews\":[],\"operatingSystems\":[]},\"webPage\":{\"webPageType\":\"WebPage\"},\"blockGraphs\":[]}","pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":"-1","robots_max_videopreview":"-1","robots_max_imagepreview":"large","priority":null,"frequency":"default","location":null,"local_seo":null,"breadcrumb_settings":null,"limit_modified_date":false,"ai":null,"created":"2022-08-12 12:30:26","updated":"2025-12-12 07:57:11","seo_analyzer_scan_date":null,"focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"author_meta":{"display_name":"Marius Bancila","author_link":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/"},"featured_img":null,"jetpack_publicize_connections":[],"uagb_featured_image_src":{"full":false,"thumbnail":false,"medium":false,"medium_large":false,"large":false,"1536x1536":false,"2048x2048":false},"uagb_author_info":{"display_name":"Marius Bancila","author_link":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/"},"uagb_comment_info":3,"uagb_excerpt":"The C++23 standard will feature a new utility type called std::expected. This type either contains an expected value, or an unexpected one, typically providing information about the reason something failed (and the expected value could not be returned). This feature is, at this time, supported in GCC 12 and MSVC 19.33 (Visual Studio 2022 17.3).&hellip;","coauthors":[],"tax_additional":{"categories":{"linked":["<a href=\"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/c\/\" class=\"advgb-post-tax-term\">C++<\/a>"],"unlinked":["<span class=\"advgb-post-tax-term\">C++<\/span>"]},"tags":{"linked":["<a href=\"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/c\/\" class=\"advgb-post-tax-term\">C++<\/a>","<a href=\"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/c\/\" class=\"advgb-post-tax-term\">C++23<\/a>","<a href=\"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/c\/\" class=\"advgb-post-tax-term\">std::expected<\/a>"],"unlinked":["<span class=\"advgb-post-tax-term\">C++<\/span>","<span class=\"advgb-post-tax-term\">C++23<\/span>","<span class=\"advgb-post-tax-term\">std::expected<\/span>"]}},"comment_count":"3","relative_dates":{"created":"Posted 4 years ago","modified":"Updated 4 years ago"},"absolute_dates":{"created":"Posted on August 17, 2022","modified":"Updated on August 17, 2022"},"absolute_dates_time":{"created":"Posted on August 17, 2022 9:53 pm","modified":"Updated on August 17, 2022 9:53 pm"},"featured_img_caption":"","series_order":"","jetpack_shortlink":"https:\/\/wp.me\/pYNdv-1b3","jetpack_sharing_enabled":true,"jetpack_likes_enabled":true,"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/posts\/4529","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/comments?post=4529"}],"version-history":[{"count":11,"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/posts\/4529\/revisions"}],"predecessor-version":[{"id":4541,"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/posts\/4529\/revisions\/4541"}],"wp:attachment":[{"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/media?parent=4529"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/categories?post=4529"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/tags?post=4529"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}