{"id":53,"date":"2020-01-18T11:44:44","date_gmt":"2020-01-18T09:44:44","guid":{"rendered":"http:\/\/www.juustila.com\/antti\/?p=53"},"modified":"2020-01-18T12:10:16","modified_gmt":"2020-01-18T10:10:16","slug":"adopting-some-newer-c-features","status":"publish","type":"post","link":"https:\/\/www.juustila.com\/antti\/2020\/01\/18\/adopting-some-newer-c-features\/","title":{"rendered":"Adopting some newer C++ features"},"content":{"rendered":"<p>I&#8217;ve been continuously updating my skills in C++, adopting features from newer features of the language, like from the version C++17. For fun and learning, I&#8217;ve been updating some older apps to use these newer features, and implementing some new tools adopting newer features like std::variant, algorithms (instead of traditional loops) and attributes. Some examples below.<\/p>\n<h3>Attributes<\/h3>\n<p>Instead of commenting in a switch\/case structure that <a href=\"https:\/\/stackoverflow.com\/questions\/188461\/switch-statement-fallthrough-should-it-be-allowed\">fallthrough is OK<\/a>, use the [[fallthrough]] attribute:<\/p>\n\n\n<!-- HTML generated using hilite.me --><div style=\"background: #111111; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;\"><pre style=\"margin: 0; line-height: 125%\">      <span style=\"color: #fb660a; font-weight: bold\">switch<\/span> <span style=\"color: #ffffff\">(argc)<\/span> <span style=\"color: #ffffff\">{<\/span>\n         <span style=\"color: #fb660a; font-weight: bold\">case<\/span> <span style=\"color: #0086f7; font-weight: bold\">4<\/span>:\n            <span style=\"color: #ffffff\">outputFileName<\/span> <span style=\"color: #ffffff\">=<\/span> <span style=\"color: #ffffff\">argv[<\/span><span style=\"color: #0086f7; font-weight: bold\">3<\/span><span style=\"color: #ffffff\">];<\/span>\n            <span style=\"color: #ffffff\">[[fallthrough]];<\/span>\n            \n         <span style=\"color: #fb660a; font-weight: bold\">case<\/span> <span style=\"color: #0086f7; font-weight: bold\">3<\/span>:\n<\/pre><\/div>\n\n\n\n<p>Reader is then aware that the missing break; is not actually missing by accident, but intentional. Improves code readability and quality, and silences the compiler warning about the missing break.<\/p>\n\n\n\n<p>To make sure the caller of the function handles the return value, use the [[nodiscard]] attribute:<\/p>\n\n\n\n<!-- HTML generated using hilite.me --><div style=\"background: #111111; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;\"><pre style=\"margin: 0; line-height: 125%\"><span style=\"color: #ffffff\">[[nodiscard]]<\/span>\n<span style=\"color: #cdcaa9; font-weight: bold\">int<\/span> <span style=\"color: #ffffff\">readFile(<\/span><span style=\"color: #fb660a; font-weight: bold\">const<\/span> <span style=\"color: #ffffff\">std::string<\/span> <span style=\"color: #ffffff\">&amp;<\/span> <span style=\"color: #ffffff\">fileName,<\/span> <span style=\"color: #ffffff\">std::vector&lt;std::string&gt;<\/span> <span style=\"color: #ffffff\">&amp;<\/span> <span style=\"color: #ffffff\">entries);<\/span>\n<\/pre><\/div>\n\n\n\n<p>Compiler will warn you that the return value is not handled. This again improves code quality.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"77\" src=\"http:\/\/www.juustila.com\/antti\/wp-content\/uploads\/2020\/01\/N\u00e4ytt\u00f6kuva-2020-1-18-kello-10.11.23-1024x77.png\" alt=\"\" class=\"wp-image-70\" srcset=\"https:\/\/www.juustila.com\/antti\/wp-content\/uploads\/2020\/01\/N\u00e4ytt\u00f6kuva-2020-1-18-kello-10.11.23-1024x77.png 1024w, https:\/\/www.juustila.com\/antti\/wp-content\/uploads\/2020\/01\/N\u00e4ytt\u00f6kuva-2020-1-18-kello-10.11.23-300x23.png 300w, https:\/\/www.juustila.com\/antti\/wp-content\/uploads\/2020\/01\/N\u00e4ytt\u00f6kuva-2020-1-18-kello-10.11.23-768x58.png 768w, https:\/\/www.juustila.com\/antti\/wp-content\/uploads\/2020\/01\/N\u00e4ytt\u00f6kuva-2020-1-18-kello-10.11.23-1536x116.png 1536w, https:\/\/www.juustila.com\/antti\/wp-content\/uploads\/2020\/01\/N\u00e4ytt\u00f6kuva-2020-1-18-kello-10.11.23-1568x118.png 1568w, https:\/\/www.juustila.com\/antti\/wp-content\/uploads\/2020\/01\/N\u00e4ytt\u00f6kuva-2020-1-18-kello-10.11.23.png 1696w\" sizes=\"auto, (max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px\" \/><figcaption>nodiscard attribute warns you that essential return value is not handled.<\/figcaption><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Using using instead of typedef<\/h3>\n\n\n\n<p>I wanted to use a shorter name for a complex data structure. Usually done with <code>typedef<\/code>. Instead, using the <code>using<\/code> keyword, the one used usually with namespaces, is neat:<\/p>\n\n\n\n<!-- HTML generated using hilite.me --><div style=\"background: #111111; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;\"><pre style=\"margin: 0; line-height: 125%\"><span style=\"color: #fb660a; font-weight: bold\">using<\/span> <span style=\"color: #ffffff\">queue_package_type<\/span> <span style=\"color: #ffffff\">=<\/span> <span style=\"color: #ffffff\">std::map&lt;std::string,<\/span> <span style=\"color: #ffffff\">std::pair&lt;<\/span><span style=\"color: #cdcaa9; font-weight: bold\">int<\/span><span style=\"color: #ffffff\">,<\/span><span style=\"color: #cdcaa9; font-weight: bold\">int<\/span><span style=\"color: #ffffff\">&gt;&gt;;<\/span>\n<span style=\"color: #ffffff\">queue_package_type<\/span> <span style=\"color: #ffffff\">queuePackageCounts;<\/span>\n<\/pre><\/div>\n\n\n\n<p>Or similarily:<\/p>\n\n\n\n<!-- HTML generated using hilite.me --><div style=\"background: #111111; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;\"><pre style=\"margin: 0; line-height: 125%\"><span style=\"color: #fb660a; font-weight: bold\">using<\/span> <span style=\"color: #ffffff\">NodeContainer<\/span> <span style=\"color: #ffffff\">=<\/span> <span style=\"color: #ffffff\">std::vector&lt;NodeView&gt;;<\/span>\n<span style=\"color: #ffffff\">NodeContainer<\/span> <span style=\"color: #ffffff\">nodes;<\/span>\n<span style=\"color: #008800; font-style: italic; background-color: #0f140f\">\/\/ ...<\/span>\n<span style=\"color: #ffffff\">SPConfigurator::NodeContainer<\/span> <span style=\"color: #ffffff\">nodes<\/span> <span style=\"color: #ffffff\">=<\/span> <span style=\"color: #ffffff\">configurator-&gt;getNodes();<\/span>\n<span style=\"color: #ffffff\">std::for_each(std::begin(nodes),<\/span> <span style=\"color: #ffffff\">std::end(nodes),<\/span> <span style=\"color: #ffffff\">[<\/span><span style=\"color: #fb660a; font-weight: bold\">this<\/span><span style=\"color: #ffffff\">](<\/span><span style=\"color: #fb660a; font-weight: bold\">const<\/span> <span style=\"color: #ffffff\">NodeView<\/span> <span style=\"color: #ffffff\">&amp;<\/span> <span style=\"color: #ffffff\">node)<\/span> <span style=\"color: #ffffff\">{<\/span>\n   <span style=\"color: #ffffff\">std::string<\/span> <span style=\"color: #ffffff\">description<\/span> <span style=\"color: #ffffff\">=<\/span> <span style=\"color: #ffffff\">node.getInputAddressWithPort()<\/span> <span style=\"color: #ffffff\">+<\/span> <span style=\"color: #0086d2\">\"\\t\"<\/span> <span style=\"color: #ffffff\">+<\/span> <span style=\"color: #ffffff\">node.getName()<\/span> <span style=\"color: #ffffff\">+<\/span> <span style=\"color: #0086d2\">\"\\t\"<\/span> <span style=\"color: #ffffff\">+<\/span> <span style=\"color: #ffffff\">node.getOutputAddressWithPort();<\/span>\n   <span style=\"color: #ffffff\">QString<\/span> <span style=\"color: #ffffff\">logEntry<\/span> <span style=\"color: #ffffff\">=<\/span> <span style=\"color: #ffffff\">QString::fromStdString(description);<\/span>\n   <span style=\"color: #ffffff\">ui-&gt;LogView-&gt;appendPlainText(logEntry);<\/span>\n<span style=\"color: #ffffff\">});<\/span>\n<\/pre><\/div>\n\n\n\n<p>Small thing but makes better looking code, in my opinion. When working with templates, The alias declaration with <code>using<\/code> is compatible with templates, whereas the C style <a href=\"https:\/\/stackoverflow.com\/questions\/10747810\/what-is-the-difference-between-typedef-and-using-in-c11\">typedef is not<\/a>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Algorithms<\/h3>\n\n\n\n<p>In a <a href=\"http:\/\/www.juustila.com\/antti\/2019\/12\/13\/generating-test-data-with-c\/\">recent post<\/a>, I mentioned algorithms like <code>std::iota<\/code> and <code>std::shuffle<\/code>, useful in generating test data. When handling containers (vectors, lists), the &#8220;old way&#8221; is to use either indexes or iterators to handle the items. Implementing these carelessly may lead to bugs. The better alternative is to use algorithms from the standard library, readily developed and rigorously tested, also considering performance. An example from a small tool app I recently made, which searches if id values read from one file are contained in lines read from another file:<\/p>\n\n\n\n<!-- HTML generated using hilite.me --><div style=\"background: #111111; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;\"><pre style=\"margin: 0; line-height: 125%\"><span style=\"color: #ffffff\">std::for_each(std::begin(indexes),<\/span> <span style=\"color: #ffffff\">std::end(indexes),<\/span> <span style=\"color: #ffffff\">[&amp;matchCount,<\/span> <span style=\"color: #ffffff\">&amp;dataEntries,<\/span> <span style=\"color: #ffffff\">&amp;output](<\/span><span style=\"color: #fb660a; font-weight: bold\">const<\/span> <span style=\"color: #ffffff\">std::string<\/span> <span style=\"color: #ffffff\">&amp;<\/span> <span style=\"color: #ffffff\">index)<\/span> <span style=\"color: #ffffff\">{<\/span>\n   <span style=\"color: #ffffff\">std::any_of(std::begin(dataEntries),<\/span> <span style=\"color: #ffffff\">std::end(dataEntries),<\/span> <span style=\"color: #ffffff\">[&amp;matchCount,<\/span> <span style=\"color: #ffffff\">&amp;index,<\/span> <span style=\"color: #ffffff\">&amp;output](<\/span><span style=\"color: #fb660a; font-weight: bold\">const<\/span> <span style=\"color: #ffffff\">std::string<\/span> <span style=\"color: #ffffff\">&amp;<\/span> <span style=\"color: #ffffff\">dataEntry)<\/span> <span style=\"color: #ffffff\">{<\/span>\n      <span style=\"color: #fb660a; font-weight: bold\">if<\/span> <span style=\"color: #ffffff\">(dataEntry.find(index)<\/span> <span style=\"color: #ffffff\">!=<\/span> <span style=\"color: #ffffff\">std::string::npos)<\/span> <span style=\"color: #ffffff\">{<\/span>\n         <span style=\"color: #ffffff\">*output<\/span> <span style=\"color: #ffffff\">&lt;&lt;<\/span> <span style=\"color: #ffffff\">matchCount+<\/span><span style=\"color: #0086f7; font-weight: bold\">1<\/span> <span style=\"color: #ffffff\">&lt;&lt;<\/span> <span style=\"color: #0086d2\">\"   \"<\/span> <span style=\"color: #ffffff\">&lt;&lt;<\/span> <span style=\"color: #ffffff\">dataEntry<\/span> <span style=\"color: #ffffff\">&lt;&lt;<\/span> <span style=\"color: #ffffff\">std::endl;<\/span>\n         <span style=\"color: #ffffff\">matchCount++;<\/span>\n         <span style=\"color: #fb660a; font-weight: bold\">return<\/span> <span style=\"color: #ffffff\">true;<\/span> <span style=\"color: #008800; font-style: italic; background-color: #0f140f\">\/\/ Not returning from the app but from the lambda function.<\/span>\n      <span style=\"color: #ffffff\">}<\/span>\n      <span style=\"color: #fb660a; font-weight: bold\">return<\/span> <span style=\"color: #ffffff\">false;<\/span>   <span style=\"color: #008800; font-style: italic; background-color: #0f140f\">\/\/ Not returning from the app but from the lambda function.<\/span>\n   <span style=\"color: #ffffff\">});<\/span>\n<span style=\"color: #ffffff\">});<\/span>\n<\/pre><\/div>\n\n\n\n<p><code>std::for_each<\/code> replaces loops created by using iterators (or indexes to the container), and when some additional logic is needed, <code>std::any_of<\/code> is a nice solution to end the search when a match is found. <\/p>\n\n\n\n<p>A bit more complicated example, using <code>std::find_if<\/code>, <code>std::all_of<\/code> and a boolean predicate object assisting in the search when calling <code>std::find_if<\/code>. In this example (<a href=\"https:\/\/bitbucket.org\/anttijuu\/entitymanipulatorexample\/src\/master\/\">full source code is here<\/a>), there is a composite design pattern implemented for handling hierarchical key-value -pairs. The code sample below implements removing a specific key-value pair from the object hierarchy.<\/p>\n\n\n\n<!-- HTML generated using hilite.me --><div style=\"background: #111111; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;\"><pre style=\"margin: 0; line-height: 125%\"><span style=\"color: #008800; font-style: italic; background-color: #0f140f\">\/**<\/span>\n<span style=\"color: #008800; font-style: italic; background-color: #0f140f\"> A helper struct to assist in finding an Entity with a given name. Used<\/span>\n<span style=\"color: #008800; font-style: italic; background-color: #0f140f\"> in EntityComposite::remove(const std::string &amp;) to find an Entity with a given name.<\/span>\n<span style=\"color: #008800; font-style: italic; background-color: #0f140f\"> *\/<\/span>\n<span style=\"color: #fb660a; font-weight: bold\">struct<\/span> <span style=\"color: #ffffff\">ElementNameMatches<\/span> <span style=\"color: #ffffff\">{<\/span>\n   <span style=\"color: #ffffff\">ElementNameMatches(<\/span><span style=\"color: #fb660a; font-weight: bold\">const<\/span> <span style=\"color: #ffffff\">std::pair&lt;std::string,std::string&gt;<\/span> <span style=\"color: #ffffff\">&amp;<\/span> <span style=\"color: #ffffff\">nameValue)<\/span> <span style=\"color: #ffffff\">{<\/span>\n      <span style=\"color: #ffffff\">searchNameValue<\/span> <span style=\"color: #ffffff\">=<\/span> <span style=\"color: #ffffff\">nameValue;<\/span>\n   <span style=\"color: #ffffff\">}<\/span>\n   <span style=\"color: #ffffff\">std::pair&lt;std::string,std::string&gt;<\/span> <span style=\"color: #ffffff\">searchNameValue;<\/span>\n   <span style=\"color: #cdcaa9; font-weight: bold\">bool<\/span> <span style=\"color: #ff0086; font-weight: bold\">operator<\/span><span style=\"color: #ffffff\">()<\/span> <span style=\"color: #ffffff\">(<\/span><span style=\"color: #fb660a; font-weight: bold\">const<\/span> <span style=\"color: #ffffff\">Entity<\/span> <span style=\"color: #ffffff\">*<\/span> <span style=\"color: #ffffff\">e)<\/span> <span style=\"color: #ffffff\">{<\/span>\n      <span style=\"color: #fb660a; font-weight: bold\">return<\/span> <span style=\"color: #ffffff\">(e-&gt;getName()<\/span> <span style=\"color: #ffffff\">==<\/span> <span style=\"color: #ffffff\">searchNameValue.first<\/span> <span style=\"color: #ffffff\">&amp;&amp;<\/span> <span style=\"color: #ffffff\">e-&gt;getValue()<\/span> <span style=\"color: #ffffff\">==<\/span> <span style=\"color: #ffffff\">searchNameValue.second);<\/span>\n   <span style=\"color: #ffffff\">}<\/span>\n<span style=\"color: #ffffff\">};<\/span>\n\n<span style=\"color: #008800; font-style: italic; background-color: #0f140f\">\/**<\/span>\n<span style=\"color: #008800; font-style: italic; background-color: #0f140f\"> Removes and deletes a child entity from this Entity.<\/span>\n<span style=\"color: #008800; font-style: italic; background-color: #0f140f\"> If the child is not an immediate child of this entity, then it is given<\/span>\n<span style=\"color: #008800; font-style: italic; background-color: #0f140f\"> to the children to be removed from there, if it is found.<\/span>\n<span style=\"color: #008800; font-style: italic; background-color: #0f140f\"> If the child is a Composite, removes and deletes the children too.<\/span>\n<span style=\"color: #008800; font-style: italic; background-color: #0f140f\"> @param nameValue A child with the equal name and value properties to remove from this entity.<\/span>\n<span style=\"color: #008800; font-style: italic; background-color: #0f140f\"> @return Returns true if the entity was removed, otherwise false.<\/span>\n<span style=\"color: #008800; font-style: italic; background-color: #0f140f\"> *\/<\/span>\n<span style=\"color: #cdcaa9; font-weight: bold\">bool<\/span> <span style=\"color: #ffffff\">EntityComposite::remove(<\/span><span style=\"color: #fb660a; font-weight: bold\">const<\/span> <span style=\"color: #ffffff\">std::pair&lt;std::string,std::string&gt;<\/span> <span style=\"color: #ffffff\">&amp;<\/span> <span style=\"color: #ffffff\">nameValue)<\/span> <span style=\"color: #ffffff\">{<\/span>\n   <span style=\"color: #cdcaa9; font-weight: bold\">bool<\/span> <span style=\"color: #ffffff\">returnValue<\/span> <span style=\"color: #ffffff\">=<\/span> <span style=\"color: #ffffff\">false;<\/span>\n   <span style=\"color: #fb660a; font-weight: bold\">auto<\/span> <span style=\"color: #ffffff\">iter<\/span> <span style=\"color: #ffffff\">=<\/span> <span style=\"color: #ffffff\">std::find_if(children.begin(),<\/span> <span style=\"color: #ffffff\">children.end(),<\/span> <span style=\"color: #ffffff\">ElementNameMatches(nameValue));<\/span>\n   <span style=\"color: #fb660a; font-weight: bold\">if<\/span> <span style=\"color: #ffffff\">(iter<\/span> <span style=\"color: #ffffff\">!=<\/span> <span style=\"color: #ffffff\">children.end())<\/span> <span style=\"color: #ffffff\">{<\/span>\n      <span style=\"color: #ffffff\">Entity<\/span> <span style=\"color: #ffffff\">*<\/span> <span style=\"color: #ffffff\">entity<\/span> <span style=\"color: #ffffff\">=<\/span> <span style=\"color: #ffffff\">*iter;<\/span>\n      <span style=\"color: #ffffff\">children.remove(*iter);<\/span>\n      <span style=\"color: #fb660a; font-weight: bold\">delete<\/span> <span style=\"color: #ffffff\">entity;<\/span>\n      <span style=\"color: #ffffff\">returnValue<\/span> <span style=\"color: #ffffff\">=<\/span> <span style=\"color: #ffffff\">true;<\/span>\n   <span style=\"color: #ffffff\">}<\/span> <span style=\"color: #fb660a; font-weight: bold\">else<\/span> <span style=\"color: #ffffff\">{<\/span>\n      <span style=\"color: #008800; font-style: italic; background-color: #0f140f\">\/\/ child was not an immediate child. Check if one of the children (or their child) has the child.<\/span>\n      <span style=\"color: #008800; font-style: italic; background-color: #0f140f\">\/\/ Use a lambda function to go through the children to find and delete the child.<\/span>\n      <span style=\"color: #008800; font-style: italic; background-color: #0f140f\">\/\/ std::all_of can be stopped when the child is found by returning false from the lambda.<\/span>\n      <span style=\"color: #ffffff\">std::all_of(children.begin(),<\/span> <span style=\"color: #ffffff\">children.end(),<\/span> <span style=\"color: #ffffff\">[nameValue,<\/span> <span style=\"color: #ffffff\">&amp;returnValue](Entity<\/span> <span style=\"color: #ffffff\">*<\/span> <span style=\"color: #ffffff\">entity)<\/span> <span style=\"color: #ffffff\">{<\/span>\n         <span style=\"color: #fb660a; font-weight: bold\">if<\/span> <span style=\"color: #ffffff\">(entity-&gt;remove(nameValue))<\/span> <span style=\"color: #ffffff\">{<\/span>\n            <span style=\"color: #ffffff\">returnValue<\/span> <span style=\"color: #ffffff\">=<\/span> <span style=\"color: #ffffff\">true;<\/span>\n            <span style=\"color: #fb660a; font-weight: bold\">return<\/span> <span style=\"color: #ffffff\">false;<\/span>\n         <span style=\"color: #ffffff\">}<\/span> <span style=\"color: #fb660a; font-weight: bold\">else<\/span> <span style=\"color: #ffffff\">{<\/span>\n            <span style=\"color: #fb660a; font-weight: bold\">return<\/span> <span style=\"color: #ffffff\">true;<\/span>\n         <span style=\"color: #ffffff\">}<\/span>\n      <span style=\"color: #ffffff\">});<\/span>\n   <span style=\"color: #ffffff\">}<\/span>\n   <span style=\"color: #fb660a; font-weight: bold\">return<\/span> <span style=\"color: #ffffff\">returnValue;<\/span>\n<span style=\"color: #ffffff\">}<\/span>\n\n<span style=\"color: #008800; font-style: italic; background-color: #0f140f\">\/\/ And then call remove() like this, for example, with <\/span>\n<span style=\"color: #008800; font-style: italic; background-color: #0f140f\">\/\/ key \"customer\", and value \"Antti Juustila\":<\/span>\n<span style=\"color: #ffffff\">newComposite-&gt;remove({<\/span><span style=\"color: #0086d2\">\"customer\"<\/span><span style=\"color: #ffffff\">,<\/span> <span style=\"color: #0086d2\">\"Antti Juustila\"<\/span><span style=\"color: #ffffff\">});<\/span>\n<\/pre><\/div>\n\n\n\n<p>What you get is more robust code without your own bugs implemented in &#8220;custom&#8221; loops with indexes and iterators.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">std::variant from C++17<\/h3>\n\n\n\n<p>What if your app has some data that can be manipulated in two formats? For example, first you get the data from the network in JSON, and then later you parse the JSON string and create an application specific object holding that parsed data. Later on, you again export the data from the internal object type to JSON to be send over to the network. <\/p>\n\n\n\n<p>You could implement this so that you have both the JSON\/string object <em>and<\/em> the application internal class object in memory. Then just add logic to know which currently has the data and should be used, and ignore the other variable until it is needed. An alternative is to use the good old <code><a href=\"https:\/\/en.cppreference.com\/w\/cpp\/language\/union\">union<\/a><\/code> to handle this, if you want to save memory. This could be quite <a href=\"https:\/\/stackoverflow.com\/questions\/42082328\/where-to-use-stdvariant-over-union\">complicated to implement<\/a>.<\/p>\n\n\n\n<p>C++17 provides a more well managed option &#8212; <code>std::<\/code><a href=\"https:\/\/en.cppreference.com\/w\/cpp\/utility\/variant\"><code>variant<\/code><\/a>. When using union, you have to keep track what the union contains, but using the variant, it knows which type of object it is currently holding and you can check that. <\/p>\n\n\n\n<p>Following the scenario above, a class could have a member variable holding the JSON in a string, <em>or<\/em> alternatively, after parsing it, in an application specific object, within an unique pointer assisting with memory management:<\/p>\n\n\n\n<!-- HTML generated using hilite.me --><div style=\"background: #111111; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;\"><pre style=\"margin: 0; line-height: 125%\"><span style=\"color: #ffffff\">std::variant&lt;std::string,<\/span> <span style=\"color: #ffffff\">std::unique_ptr&lt;DataItem&gt;&gt;<\/span> <span style=\"color: #ffffff\">payload;<\/span>\n<\/pre><\/div>\n\n\n\n<p>In the class containing the payload member variable, you can initialise it to an empty string:<\/p>\n\n\n\n<!-- HTML generated using hilite.me --><div style=\"background: #111111; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;\"><pre style=\"margin: 0; line-height: 125%\"><span style=\"color: #ffffff\">Package::Package()<\/span>\n<span style=\"color: #ffffff\">:<\/span> <span style=\"color: #ffffff\">payload(<\/span><span style=\"color: #0086d2\">\"\"<\/span><span style=\"color: #ffffff\">)<\/span>\n<\/pre><\/div>\n\n\n\n<p>Then you can provide setters to change from one representation of the data to another:<\/p>\n\n\n\n<!-- HTML generated using hilite.me --><div style=\"background: #111111; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;\"><pre style=\"margin: 0; line-height: 125%\"><span style=\"color: #008800; font-style: italic; background-color: #0f140f\">\/\/ Set the data to be a JSON string:<\/span>\n<span style=\"color: #cdcaa9; font-weight: bold\">void<\/span> <span style=\"color: #ffffff\">Package::setPayload(<\/span><span style=\"color: #fb660a; font-weight: bold\">const<\/span> <span style=\"color: #ffffff\">std::string<\/span> <span style=\"color: #ffffff\">&amp;<\/span> <span style=\"color: #ffffff\">d)<\/span> <span style=\"color: #ffffff\">{<\/span>\n   <span style=\"color: #ffffff\">payload<\/span> <span style=\"color: #ffffff\">=<\/span> <span style=\"color: #ffffff\">d;<\/span>\n<span style=\"color: #ffffff\">}<\/span>\n<span style=\"color: #008800; font-style: italic; background-color: #0f140f\">\/\/ ...or a DataItem object, parsed from the string:<\/span>\n<span style=\"color: #cdcaa9; font-weight: bold\">void<\/span> <span style=\"color: #ffffff\">Package::setPayload(std::unique_ptr&lt;DataItem&gt;<\/span> <span style=\"color: #ffffff\">item)<\/span> <span style=\"color: #ffffff\">{<\/span>\n   <span style=\"color: #ffffff\">payload<\/span> <span style=\"color: #ffffff\">=<\/span> <span style=\"color: #ffffff\">std::move(item);<\/span>\n<span style=\"color: #ffffff\">}<\/span>\n<\/pre><\/div>\n\n\n\n<p>When you access the data to use it somewhere, you can check what is actually stored in the variant and return it. If the representation is not the one requested, return an empty value or null pointer to indicate to the caller that the requested representation of the data is not available currently:<\/p>\n\n\n\n<!-- HTML generated using hilite.me --><div style=\"background: #111111; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;\"><pre style=\"margin: 0; line-height: 125%\"><span style=\"color: #008800; font-style: italic; background-color: #0f140f\">\/\/ Get the string, using std::get_if:<\/span>\n<span style=\"color: #fb660a; font-weight: bold\">const<\/span> <span style=\"color: #ffffff\">std::string<\/span> <span style=\"color: #ffffff\">&amp;<\/span> <span style=\"color: #ffffff\">Package::getPayloadString()<\/span> <span style=\"color: #fb660a; font-weight: bold\">const<\/span> <span style=\"color: #ffffff\">{<\/span>\n   <span style=\"color: #fb660a; font-weight: bold\">auto<\/span> <span style=\"color: #ffffff\">item<\/span> <span style=\"color: #ffffff\">=<\/span> <span style=\"color: #ffffff\">std::get_if&lt;std::string&gt;(&amp;payload);<\/span>\n   <span style=\"color: #fb660a; font-weight: bold\">if<\/span> <span style=\"color: #ffffff\">(item)<\/span> <span style=\"color: #ffffff\">{<\/span>\n      <span style=\"color: #fb660a; font-weight: bold\">return<\/span> <span style=\"color: #ffffff\">*item;<\/span>\n   <span style=\"color: #ffffff\">}<\/span>\n   <span style=\"color: #fb660a; font-weight: bold\">return<\/span> <span style=\"color: #ffffff\">emptyString;<\/span>\n<span style=\"color: #ffffff\">}<\/span>\n<span style=\"color: #008800; font-style: italic; background-color: #0f140f\">\/\/ Get the DataItem, using std::get_if<\/span>\n<span style=\"color: #fb660a; font-weight: bold\">const<\/span> <span style=\"color: #ffffff\">DataItem<\/span> <span style=\"color: #ffffff\">*<\/span> <span style=\"color: #ffffff\">Package::getPayloadObject()<\/span> <span style=\"color: #fb660a; font-weight: bold\">const<\/span> <span style=\"color: #ffffff\">{<\/span>\n   <span style=\"color: #fb660a; font-weight: bold\">auto<\/span> <span style=\"color: #ffffff\">item<\/span> <span style=\"color: #ffffff\">=<\/span> <span style=\"color: #ffffff\">std::get_if&lt;std::unique_ptr&lt;DataItem&gt;&gt;(&amp;payload);<\/span>\n   <span style=\"color: #fb660a; font-weight: bold\">if<\/span> <span style=\"color: #ffffff\">(item)<\/span> <span style=\"color: #ffffff\">{<\/span>\n      <span style=\"color: #fb660a; font-weight: bold\">return<\/span> <span style=\"color: #ffffff\">item-&gt;get();<\/span>\n   <span style=\"color: #ffffff\">}<\/span>\n   <span style=\"color: #fb660a; font-weight: bold\">return<\/span> <span style=\"color: #ffffff\">nullptr;<\/span>\n<span style=\"color: #ffffff\">}<\/span>\n<\/pre><\/div>\n\n\n\n<p>Next I&#8217;d like to take a look at how to use the new async programming features of C++, as well as the Boost asio library&#8230;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I&#8217;ve been continuously updating my skills in C++, adopting features from newer features of the language, like from the version C++17. For fun and learning, I&#8217;ve been updating some older apps to use these newer features, and implementing some new tools adopting newer features like std::variant, algorithms (instead of traditional loops) and attributes. Some examples &hellip; <a href=\"https:\/\/www.juustila.com\/antti\/2020\/01\/18\/adopting-some-newer-c-features\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Adopting some newer C++ features&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"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":""},"categories":[2],"tags":[27,10,11,28],"class_list":["post-53","post","type-post","status-publish","format-standard","hentry","category-coding","tag-attributes","tag-c","tag-cstd","tag-stdvariant"],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.juustila.com\/antti\/wp-json\/wp\/v2\/posts\/53","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.juustila.com\/antti\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.juustila.com\/antti\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.juustila.com\/antti\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.juustila.com\/antti\/wp-json\/wp\/v2\/comments?post=53"}],"version-history":[{"count":5,"href":"https:\/\/www.juustila.com\/antti\/wp-json\/wp\/v2\/posts\/53\/revisions"}],"predecessor-version":[{"id":75,"href":"https:\/\/www.juustila.com\/antti\/wp-json\/wp\/v2\/posts\/53\/revisions\/75"}],"wp:attachment":[{"href":"https:\/\/www.juustila.com\/antti\/wp-json\/wp\/v2\/media?parent=53"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.juustila.com\/antti\/wp-json\/wp\/v2\/categories?post=53"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.juustila.com\/antti\/wp-json\/wp\/v2\/tags?post=53"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}