{"id":666,"date":"2017-10-21T03:25:09","date_gmt":"2017-10-21T03:25:09","guid":{"rendered":"http:\/\/www.rangakrish.com\/?p=666"},"modified":"2017-10-21T07:52:10","modified_gmt":"2017-10-21T07:52:10","slug":"c17-initalization-in-selection-statements","status":"publish","type":"post","link":"https:\/\/www.rangakrish.com\/index.php\/2017\/10\/21\/c17-initalization-in-selection-statements\/","title":{"rendered":"C++17: Initialization in Selection Statements"},"content":{"rendered":"<p>C++17 enhances <em><strong>if<\/strong><\/em> and <em><strong>switch<\/strong><\/em> statements with the ability to define\u00a0 variables whose life-time is limited to the corresponding scope. This is in keeping with the general guideline that variables should have a <em><strong>tight<\/strong><\/em> scope, i.e.,\u00a0 should be defined as close to the point of use as possible and should not live beyond where they are really needed.<\/p>\n<p>What are the main benefits of such a tight scoping?<\/p>\n<p style=\"padding-left: 30px;\">&#8211; Name pollution is under control<\/p>\n<p style=\"padding-left: 30px;\">&#8211; As per <a href=\"http:\/\/en.cppreference.com\/w\/cpp\/language\/raii\" target=\"_blank\" rel=\"noopener\"><em><strong>RAII<\/strong><\/em><\/a>, acquired resources are released as early as possible<\/p>\n<p>Prior to C++17, it was possible to define variables in the <em><strong>if<\/strong><\/em> statement, but with the condition that for user-defined types, the type must define either <em><strong>operator bool()<\/strong><\/em> or <em><strong>operator void *()<\/strong><\/em>. C++17 removes this requirement and makes initialization much more simpler and straightforward.<\/p>\n<p>Let us consider the following struct as an example:<\/p>\n<figure id=\"attachment_667\" aria-describedby=\"caption-attachment-667\" style=\"width: 461px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2017\/10\/classdefn.png\"><img data-recalc-dims=\"1\" fetchpriority=\"high\" decoding=\"async\" data-attachment-id=\"667\" data-permalink=\"https:\/\/www.rangakrish.com\/index.php\/2017\/10\/21\/c17-initalization-in-selection-statements\/classdefn\/\" data-orig-file=\"https:\/\/www.rangakrish.com\/wp-content\/uploads\/2017\/10\/classdefn.png\" data-orig-size=\"461,478\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"Sample Class\" data-image-description=\"&lt;p&gt;Sample Class&lt;\/p&gt;\n\" data-image-caption=\"&lt;p&gt;Sample Class&lt;\/p&gt;\n\" data-large-file=\"https:\/\/www.rangakrish.com\/wp-content\/uploads\/2017\/10\/classdefn.png\" class=\"size-full wp-image-667\" src=\"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2017\/10\/classdefn.png?resize=461%2C478\" alt=\"Sample Class\" width=\"461\" height=\"478\" srcset=\"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2017\/10\/classdefn.png?w=461&amp;ssl=1 461w, https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2017\/10\/classdefn.png?resize=289%2C300&amp;ssl=1 289w\" sizes=\"(max-width: 461px) 100vw, 461px\" \/><\/a><figcaption id=\"caption-attachment-667\" class=\"wp-caption-text\"><strong>Sample Class<\/strong><\/figcaption><\/figure>\n<p>An object of this type\u00a0<em><strong>X<\/strong><\/em> is constructed by passing an integer argument. It is a valid initialization if the argument passed is less than 1000, else it is invalid. By the way, this struct has been defined merely to illustrate our idea, and has no other significance.<\/p>\n<p>Take a look at the following function:<\/p>\n<figure id=\"attachment_668\" aria-describedby=\"caption-attachment-668\" style=\"width: 498px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2017\/10\/func1.png\"><img data-recalc-dims=\"1\" decoding=\"async\" data-attachment-id=\"668\" data-permalink=\"https:\/\/www.rangakrish.com\/index.php\/2017\/10\/21\/c17-initalization-in-selection-statements\/func1\/\" data-orig-file=\"https:\/\/www.rangakrish.com\/wp-content\/uploads\/2017\/10\/func1.png\" data-orig-size=\"498,354\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"Pre-C++17 Usage\" data-image-description=\"&lt;p&gt;Pre-C++17 Usage&lt;\/p&gt;\n\" data-image-caption=\"&lt;p&gt;Pre-C++17 Usage&lt;\/p&gt;\n\" data-large-file=\"https:\/\/www.rangakrish.com\/wp-content\/uploads\/2017\/10\/func1.png\" class=\"size-full wp-image-668\" src=\"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2017\/10\/func1.png?resize=498%2C354\" alt=\"Pre-C++17 Usage\" width=\"498\" height=\"354\" srcset=\"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2017\/10\/func1.png?w=498&amp;ssl=1 498w, https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2017\/10\/func1.png?resize=300%2C213&amp;ssl=1 300w\" sizes=\"(max-width: 498px) 100vw, 498px\" \/><\/a><figcaption id=\"caption-attachment-668\" class=\"wp-caption-text\"><strong>Pre-C++17 Usage<\/strong><\/figcaption><\/figure>\n<p>It shows the initialization feature available prior to C++17. Notice how we create an object of type\u00a0<em><strong>X<\/strong><\/em> within the condition part of <em><strong>if<\/strong><\/em> statement. The scope of the object is just this <em><strong>if<\/strong><\/em> statement, extending to the <em><strong>true<\/strong><\/em> and <em><strong>false<\/strong><\/em> segments of the code.<\/p>\n<p>So how do we know if the initialization is treated as <em><strong>true<\/strong><\/em> or <em><strong>false<\/strong><\/em>? According to the standard, if the class has <em><strong>operator bool()<\/strong> <\/em>function, then it will be automatcialy invoked after the object is constructed and\u00a0 if that operator returns <em><strong>true<\/strong><\/em>, then the condition evaluates to <em><strong>true<\/strong><\/em>, else it is <em><strong>false<\/strong><\/em>. If the class does not define <em><strong>operator bool()<\/strong><\/em>, but defines <em><strong>operator void *()<\/strong><\/em>, then this function will be invoked after construction. If this returns <em><strong>nullptr<\/strong><\/em>, the condition is treated as <em><strong>false<\/strong><\/em>, else it is <em><strong>true<\/strong><\/em>. What if both functions are defined? In that case, <em><strong>operator bool()<\/strong><\/em> will be called. What if neither is defined? Then it is a compile-time error!<\/p>\n<p>Here is the output from the program:<\/p>\n<p style=\"padding-left: 30px;\"><span style=\"color: #0000ff;\"><em><strong>operator bool called<\/strong><\/em><\/span><\/p>\n<p style=\"padding-left: 30px;\"><span style=\"color: #0000ff;\"><em><strong>Object x_true inited successfully<\/strong><\/em><\/span><\/p>\n<p style=\"padding-left: 30px;\"><span style=\"color: #0000ff;\"><em><strong>operator bool called<\/strong><\/em><\/span><\/p>\n<p style=\"padding-left: 30px;\"><span style=\"color: #0000ff;\"><em><strong>Object x_false initialization failed<\/strong><\/em><\/span><\/p>\n<p>You can see that even though both the operator functions are present, the compiler calls <em><strong>operator bool()<\/strong><\/em>. The result is as expected.<\/p>\n<p>Now, what has changed in C++17? The logic has been considerably simplified by introducing a syntax extension to the <em><strong>if<\/strong><\/em> statement. Before showing how to take advantage of the new extension, I want to mention that <em><strong>switch<\/strong><\/em> statement too has been enhanced in this context.<\/p>\n<figure id=\"attachment_669\" aria-describedby=\"caption-attachment-669\" style=\"width: 510px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2017\/10\/func2.png\"><img data-recalc-dims=\"1\" decoding=\"async\" data-attachment-id=\"669\" data-permalink=\"https:\/\/www.rangakrish.com\/index.php\/2017\/10\/21\/c17-initalization-in-selection-statements\/func2\/\" data-orig-file=\"https:\/\/www.rangakrish.com\/wp-content\/uploads\/2017\/10\/func2.png\" data-orig-size=\"510,524\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"C++17 Model\" data-image-description=\"&lt;p&gt;C++17 Model&lt;\/p&gt;\n\" data-image-caption=\"&lt;p&gt;C++17 Model&lt;\/p&gt;\n\" data-large-file=\"https:\/\/www.rangakrish.com\/wp-content\/uploads\/2017\/10\/func2.png\" class=\"size-full wp-image-669\" src=\"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2017\/10\/func2.png?resize=510%2C524\" alt=\"C++17 Model\" width=\"510\" height=\"524\" srcset=\"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2017\/10\/func2.png?w=510&amp;ssl=1 510w, https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2017\/10\/func2.png?resize=292%2C300&amp;ssl=1 292w\" sizes=\"(max-width: 510px) 100vw, 510px\" \/><\/a><figcaption id=\"caption-attachment-669\" class=\"wp-caption-text\"><strong>C++17 Model<\/strong><\/figcaption><\/figure>\n<p>As is evident, the <em><strong>if<\/strong><\/em> condition can now contain two parts. The first part is the actual initialization (can be skipped if you do not want to initialize any object here) and the second part is the condition part. This is neat because we do not require <em><strong>operator bool()<\/strong><\/em> or <em><strong>operator void *()<\/strong><\/em> function to tell us if the initialization is successful.\u00a0 The condition part can directly access an appropriate element of the object to trigger the branch to be taken.<\/p>\n<p>Here is the output:<\/p>\n<p style=\"padding-left: 30px;\"><span style=\"color: #0000ff;\"><em><strong>Object x1 inited successfully<\/strong><\/em><\/span><\/p>\n<p style=\"padding-left: 30px;\"><span style=\"color: #0000ff;\"><em><strong>Object x2 initialization failed<\/strong><\/em><\/span><\/p>\n<p style=\"padding-left: 30px;\"><span style=\"color: #0000ff;\"><em><strong>Object xobj at LEVEL3<\/strong><\/em><\/span><\/p>\n<p>Neat, eh?<\/p>\n<p>Object initialization in selection statements, as explained above, is not that common, but I feel it deserves more attention. C++17 makes this usage much more palatable.<\/p>\n<p>I tested this code in <em><strong>Visual Studio Professional 2017, version 15.4.0<\/strong><\/em>. The source code is available <a href=\"http:\/\/www.rangakrish.com\/downloads\/Selection-initializer.cpp\" target=\"_blank\" rel=\"noopener\">here<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>C++17 enhances if and switch statements with the ability to define\u00a0 variables whose life-time is limited to the corresponding scope. This is in keeping with the general guideline that variables should have a tight scope, i.e.,\u00a0 should be defined as close to the point of use as possible and should not live beyond where they [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"advanced_seo_description":"","jetpack_seo_html_title":"","jetpack_seo_noindex":false,"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[49,17],"tags":[118,119,120],"class_list":["post-666","post","type-post","status-publish","format-standard","hentry","category-c","category-programming","tag-c17","tag-initializer","tag-selection-statements"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p9OLnF-aK","jetpack-related-posts":[{"id":3230,"url":"https:\/\/www.rangakrish.com\/index.php\/2023\/10\/15\/c20-constinit-specifier\/","url_meta":{"origin":666,"position":0},"title":"C++20: \u201cconstinit\u201d Specifier","author":"admin","date":"October 15, 2023","format":false,"excerpt":"The constinit specifier, introduced in C++20, is applied to static variables (global and local static) and thread local variables, with the requirement that they either have a zero initialization or they are initialized with a compile-time constant expression. Here is our first example: Line 17 declares a global constinit variable,\u2026","rel":"","context":"In &quot;C++&quot;","block_context":{"text":"C++","link":"https:\/\/www.rangakrish.com\/index.php\/category\/c\/"},"img":{"alt_text":"Example-1: Basic Types","src":"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2023\/10\/case1-300x178.jpg?resize=350%2C200&ssl=1","width":350,"height":200},"classes":[]},{"id":717,"url":"https:\/\/www.rangakrish.com\/index.php\/2017\/12\/03\/c17-stdany\/","url_meta":{"origin":666,"position":1},"title":"C++17: std::any","author":"admin","date":"December 3, 2017","format":false,"excerpt":"In the previous two posts, I talked about std::variant<> and std::optional<>. Today, I want to take up std::any for discussion. The type any (implemented by the class any) allows a variable to hold a single value of any type. More interestingly, the type of the value held by a variable\u2026","rel":"","context":"In &quot;C++&quot;","block_context":{"text":"C++","link":"https:\/\/www.rangakrish.com\/index.php\/category\/c\/"},"img":{"alt_text":"Example1","src":"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2017\/12\/Example1.png?resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2017\/12\/Example1.png?resize=350%2C200 1x, https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2017\/12\/Example1.png?resize=525%2C300 1.5x"},"classes":[]},{"id":193,"url":"https:\/\/www.rangakrish.com\/index.php\/2016\/03\/27\/user-defined-literals-in-c\/","url_meta":{"origin":666,"position":2},"title":"User-defined Literals in C++","author":"admin","date":"March 27, 2016","format":false,"excerpt":"C++11 introduced user-defined literals, allowing programmers to define special suffixes that can be associated with the built-in literal types: character, integer, float, boolean, and pointer. When designed and used properly, these provide nice syntactic sugar facilitating readability and at the same time, increasing type safety. For example, I can define\u2026","rel":"","context":"In &quot;C++&quot;","block_context":{"text":"C++","link":"https:\/\/www.rangakrish.com\/index.php\/category\/c\/"},"img":{"alt_text":"User-defined Literal","src":"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2016\/03\/User-defined-Literal.png?resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2016\/03\/User-defined-Literal.png?resize=350%2C200 1x, https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2016\/03\/User-defined-Literal.png?resize=525%2C300 1.5x"},"classes":[]},{"id":1905,"url":"https:\/\/www.rangakrish.com\/index.php\/2020\/03\/04\/deleted-destructor-in-c\/","url_meta":{"origin":666,"position":3},"title":"Deleted Destructor in C++","author":"admin","date":"March 4, 2020","format":false,"excerpt":"Since C++ 11, we can use the keyword delete to declare functions as deleted and thus prohibit the use of these functions in the code. See this article\u00a0for a brief overview. In particular, the destructor of a class\/struct\/union can be declared as deleted. In today\u2019s article, I am going to\u2026","rel":"","context":"In &quot;C++&quot;","block_context":{"text":"C++","link":"https:\/\/www.rangakrish.com\/index.php\/category\/c\/"},"img":{"alt_text":"Example-8","src":"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2020\/03\/Example-8.jpg?resize=350%2C200&ssl=1","width":350,"height":200},"classes":[]},{"id":3184,"url":"https:\/\/www.rangakrish.com\/index.php\/2023\/08\/13\/stdis_scoped_enum\/","url_meta":{"origin":666,"position":4},"title":"std::is_scoped_enum","author":"admin","date":"August 13, 2023","format":false,"excerpt":"The type trait \"std::is_scoped_enum<T>::value\" was introduced in C++23 to check whether the type \u201cT\u201d is a scoped enum type. Another way to use this is std::is_scoped_enum_v<T>. Before getting into this trait in detail, let us briefly recap the differences between unscoped and scoped enums. Unscoped Enums Unscoped enums are the\u2026","rel":"","context":"In &quot;C++&quot;","block_context":{"text":"C++","link":"https:\/\/www.rangakrish.com\/index.php\/category\/c\/"},"img":{"alt_text":"Unscoped Enums","src":"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2023\/08\/unscoped-300x110.jpg?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2023\/08\/unscoped-300x110.jpg?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2023\/08\/unscoped-300x110.jpg?resize=525%2C300&ssl=1 1.5x"},"classes":[]},{"id":1960,"url":"https:\/\/www.rangakrish.com\/index.php\/2020\/04\/12\/stdcommon_type-type-trait\/","url_meta":{"origin":666,"position":5},"title":"std::common_type Type Trait","author":"admin","date":"April 12, 2020","format":false,"excerpt":"In today's post, I would like to go over the type trait std::common_type<>. This trait was introduced in C++11. As per the specification, std::common_type<T1, T2, ...Tn>::type refers to a type Tx in the given list, which the rest of the types in the list can be implicitly converted to. This\u2026","rel":"","context":"In &quot;C++&quot;","block_context":{"text":"C++","link":"https:\/\/www.rangakrish.com\/index.php\/category\/c\/"},"img":{"alt_text":"Program Output","src":"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2020\/04\/Fig5.jpg?resize=350%2C200&ssl=1","width":350,"height":200},"classes":[]}],"_links":{"self":[{"href":"https:\/\/www.rangakrish.com\/index.php\/wp-json\/wp\/v2\/posts\/666","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.rangakrish.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.rangakrish.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.rangakrish.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.rangakrish.com\/index.php\/wp-json\/wp\/v2\/comments?post=666"}],"version-history":[{"count":0,"href":"https:\/\/www.rangakrish.com\/index.php\/wp-json\/wp\/v2\/posts\/666\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.rangakrish.com\/index.php\/wp-json\/wp\/v2\/media?parent=666"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.rangakrish.com\/index.php\/wp-json\/wp\/v2\/categories?post=666"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.rangakrish.com\/index.php\/wp-json\/wp\/v2\/tags?post=666"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}