    <rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:admin="http://webns.net/mvcb/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:content="http://purl.org/rss/1.0/modules/content/">
     <channel>
        <title>ACCU  :: Code Critique Competition 119</title>
        <link>https://members.accu.org/index.php/articles/2692</link>
        <description>Professionalism in Programming</description>
        <dc:language>en-us</dc:language> 
        <dc:creator>Administrator</dc:creator> 
        <admin:generatorAgent rdf:resource="http://www.xaraya.org" /> 
        <admin:errorReportsTo rdf:resource="mailto:webeditor@accu.org" />
       <sy:updatePeriod>hourly</sy:updatePeriod>
       <sy:updateFrequency>1</sy:updateFrequency>
       <docs>http://backend.userland.com/rss</docs>




<div class="xar-mod-head"><span class="xar-mod-title">Student Code Critiques from CVu journal. + CVu Journal Vol 31, #4 - September 2019</span></div>

<table border="0" cellpadding="1" cellspacing="0">
    <tbody>
    <tr>
        <td valign="top">
            Browse in :
       </td>
       <td valign="top">

                                            <a href="https://members.accu.org/index.php/articles/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c184/">Journal Columns</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c183/">Code Critique</a>
<br />

                                            <a href="https://members.accu.org/index.php/articles/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c76/">Journals</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c77/">CVu</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c402/">314</a>
<br />

                                            <a href="https://members.accu.org/index.php/articles/c183-402/">Any of these categories</a>

                    -                        <a href="https://members.accu.org/index.php/articles/c183+402/">All of these categories</a>
<br />
</td>
   </tr>
   </tbody>
</table>




<div class="xar-error">
   <p>
 <strong>Note:</strong> when you create a new publication type,
the articles module will automatically use the templates
<em>user-display-[publicationtype].xt</em>
and <em>user-summary-[publicationtype].xt</em>.
If those templates do not exist when you try to preview or display a new article,
you'll get this warning :-)  Please place your own templates in themes/<em>yourtheme</em>/modules/articles . The templates will get the extension .xt there. </p>
</div>
<div class="xar-norm xar-standard-box-padding">
   <h1><strong>Title:</strong>&nbsp;Code Critique Competition 119</h1>
<p><strong>Author:</strong>&nbsp;Bob Schmidt</p>
<p>
<strong>Date:</strong> 03 September 2019 17:09:32 +01:00 or Tue, 03 September 2019 17:09:32 +01:00</p>
<p><strong>Summary:</strong>&nbsp;Set and collated by Roger Orr. A book prize is awarded for the best entry.</p>
<p><strong>Body:</strong>&nbsp;<p class="EditorIntro">Please note that participation in this competition is open to all members, whether novice or expert. Readers are also encouraged to comment on published entries, and to supply their own possible code samples for the competition (in any common programming language) to scc@accu.org.</p>

<p class="EditorIntro">Note: if you would rather not have your critique visible online please inform me. (Email addresses are not publicly visible.)</p>

<h2>Last issueâ€™s code</h2>

<p class="blockquote">Iâ€™m writing code to process sets of address lists, and was hoping to avoid having to make copies of the data structures by using references. However, I canâ€™t get it working â€“ Iâ€™ve produced a stripped-down example that reads sample data from a file but it doesnâ€™t work at all.</p>

<p class="blockquote">Sample data:</p>

<pre class="programlisting">
     Roger Peckham London UK
     John Beaconsfield Bucks UK
     Michael Chicago Illinois USA</pre>
	 
<p class="blockquote">Expected output:</p>
<p class="blockquote"> addresses, sorted by country and then county</p>

<p class="blockquote">Actual output:</p>
<p class="blockquote"> three blank lines!</p>

<p>Can you solve the problem â€“ and then give some further advice?</p>

<p>Listing 1 contains the code.</p>

<table class="sidebartable">
	<tr>
		<td>
			<pre class="programlisting">
#include &lt;algorithm&gt;
#include &lt;iostream&gt;
#include &lt;iterator&gt;
#include &lt;map&gt;
#include &lt;string&gt;
#include &lt;vector&gt;
struct address /* simplified */
{
  std::string city;
  std::string county;
  std::string country;
};
std::istream&amp; operator&gt;&gt;(std::istream&amp; is,
  address&amp; t)
{
  is &gt;&gt; t.city &gt;&gt; t.county &gt;&gt; t.country;
  return is;
}
std::ostream&amp; operator&lt;&lt;(std::ostream&amp; os,
  address&amp; t)
{
  os &lt;&lt; t.city &lt;&lt; ' '&lt;&lt; t.county &lt;&lt; ' '
     &lt;&lt; t.country;
  return os;
}
// sort addresses by country, county, and
// then city
bool operator&lt;(address const &amp;a,
               address const &amp; b)
{
  if (a.country &lt; b.country) return true;
  if (a.country == b.country &amp;&amp;
      a.county &lt; b.county) return true;
  if (a.country == b.country &amp;&amp;
      a.county == b.county &amp;&amp;
      a.city &lt; b.city) return true;
  return false;
}

// This is just for testing, real data
// is supplied differently
auto read(std::istream &amp;is)
{
  std::map&lt;std::string, address&gt; ret;
  while (is)
  {
    std::string name;
    address addr;
    if (is &gt;&gt; name &gt;&gt; addr)
    {
      ret[name] = addr;
    }
  }
  return ret;
}

int main()
{
  std::map&lt;std::string, address&gt; map;
  map = read(std::cin);

  // Don't copy the addresses
  std::vector&lt;std::tuple&lt;address&amp;&gt;&gt; addrs;
  for (auto entry : map)
  {
    addrs.push_back(entry.second);
  }

  // sort and print the addresses
  std::sort(addrs.begin(), addrs.end());
  for (auto&amp; v : addrs)
  {
    std::cout &lt;&lt; std::get&lt;0&gt;(v) &lt;&lt; '\n';
  }
  std::cout &lt;&lt; '\n';
}
			</pre>
		</td>
	</tr>
	<tr>
		<td class="title">Listing 1</td>
	</tr>
</table>

<h2>Critiques</h2>

<h3>Nicolas Golaszewski</h3>

<p>The Original Code (OC) wanted to spare copies by using references, which unfortunately cannot be used inside <code>std::vector</code>. Using a <code>std::tuple</code> with only one reference as the vectorâ€™s element was a nice trick. However, when it comes to sorting, this also brings in the use of swapping. Given <code>a</code> and <code>b</code> (two values of type <code>T</code>) and <code>Ra</code> and <code>Rb</code> (respectively the two references), the normal first step of swapping:</p>
 
<pre class="programlisting">
  T &amp; Rc = Ra;</pre>
  
<p>does not create a copy (of <code>a</code>) but just a synonym of <code>Ra</code>.</p>

<p>The second swapping step</p>

<pre class="programlisting">
  Ra = Rb;</pre>
  
<p>ends by getting rid of the value of <code>a</code> in favor of the value of <code>b</code>.</p>

<p>So, why not use pointers to save copies? Old time raw pointers are now discouraged. Smart <code>std::shared_ptr&lt;T&gt;</code> would maybe be too expensive when a copy of the <code>T</code> value is cheap.</p>

<p>Fortunately there exists <code>std::reference_wrapper&lt;T&gt;</code> which just... encapsulates a raw pointer to <code>T</code>.</p>

<p>So, just rewording the OC <code>addrs</code> variable</p>
 
<pre class="programlisting">
  std::vector&lt;std::tuple&lt;std::reference_wrapper&lt;address&gt;&gt;&gt; addrs;</pre>
  
<p>is enough to make things work again.</p>

<p>Other ideas on the OC came from the operator</p>

<pre class="programlisting">
  bool operator&lt;(address const &amp;a,
    address const &amp; b){...}</pre>

<p>which defines the comparison order by country first, county and city last.</p>

<p>This is exactly what the <code>operator&lt; </code>for <code>std::tuple</code> does.</p>

<p>So, the idea is to recycle the tuple trick to hold the 3 members of the address (I know the <code>address</code> class is simplified but I have seen the comparison <code>operator&lt;</code> manually redefined many times where a tuple would get the job done).</p>

<p>So, the idea is to have an empty <code>address</code> class just to define what kind of data will be used</p>

<pre class="programlisting">
  struct address  {
    // only good idea if sorting order stays
    // the same
    enum item { country = 0, county, city };
    using type = std::tuple&lt;std::string,
                 std::string,
                 std::string&gt;;
    using ref_wrap_type =
      std::reference_wrapper&lt;type&gt;;
    using ref_wrap_const_type =
      std::reference_wrapper&lt;const type&gt;;
  };</pre>
  
<p>And, for example, the input <code>operator&gt;&gt;</code> becomes</p>

<pre class="programlisting">
  std::istream&amp; operator&gt;&gt;(
    std::istream&amp; is,address::type&amp; t)
  {
    is &gt;&gt; std::get&lt;address::city&gt;(t)
       &gt;&gt; std::get&lt;address::county&gt;(t)
       &gt;&gt; std::get&lt;address::country&gt;(t);
    return is;
  }</pre>
  
<p>The most interesting thing is in the comparison <code>operator&lt;</code> â€“ we do not need <code>operator&lt;</code> for <code>address</code> as we will use the <code>operator&lt;</code> of <code>std::tuple</code>.</p>

<p>The <code>auto read(std::istream &amp;is)</code> testing function stays the same.</p>

<p>The <code>main()</code> code becomes</p>

<pre class="programlisting">
  //...
  std::map&lt;std::string, address::type&gt; map =
    read(ifs);
	
  // Don't copy the addresses
  std::vector&lt;address::ref_wrap_const_type&gt;
    addrs;
	
  for (const auto &amp; entry : map) {
    addrs.push_back(entry.second);
  }
  //...</pre>
  
<p>Note that now the <code>map</code> value type is a tuple of 3 <code>std::string</code> and that the <code>addrs</code> vector holds reference to this <code>const</code> qualified type. (Put <code>const</code> whenever possible...)</p>

<p>I thought this would be the end of the story but, naturally, the <code>std::sort</code> algorithm will look for a comparison <code>operator&lt;</code> ofâ€¦ <code>std::reference_wrapper&lt;address::type&gt;</code>â€¦ which naturally (and fortunately) does not exist.</p>

<p>Not being discouraged, the following adjustment with a lambda as comparator</p>

<pre class="programlisting">
  std::sort(addrs.begin(), addrs.end(),
         [](address::ref_wrap_const_type rwc_a,
            address::ref_wrap_const_type rwc_b)
    {return rwc_a.get() &lt; rwc_b.get();}
  );</pre>

<p>was simple enough to escape this pitfall.</p>

<p>Below is the complete code, tested on coliru just in caseâ€¦ <code>g++ -std=c++14 -O2 -Wall -pedantic main.cpp &amp;&amp; ./a.out</code></p>

<pre class="programlisting">
#include &lt;algorithm&gt;
#include &lt;iostream&gt;
#include &lt;map&gt;
#include &lt;string&gt;
#include &lt;vector&gt;
#include &lt;tuple&gt;
#include &lt;fstream&gt;
#include &lt;functional&gt;
#include &lt;sstream&gt;
struct address
{
  // only good idea if sorting order stays
  // the same
  enum item { country = 0, county, city };
  using type = std::tuple&lt;
    std::string,std::string,std::string&gt;;
  using ref_wrap_type          =
    std::reference_wrapper&lt;type&gt;;
  using ref_wrap_const_type    =
    std::reference_wrapper&lt;const type&gt;;
};
std::istream&amp; operator&gt;&gt;(
  std::istream&amp; is,address::type&amp; t)
{
  is &gt;&gt; std::get&lt;address::city&gt;(t)
     &gt;&gt; std::get&lt;address::county&gt;(t)
     &gt;&gt; std::get&lt;address::country&gt;(t);
  return is;
}

std::ostream&amp; operator&lt;&lt;(
  std::ostream&amp; os,const address::type&amp; t)
{
  os &lt;&lt; std::get&lt;address::city&gt;(t) &lt;&lt; ' '
     &lt;&lt; std::get&lt;address::county&gt;(t) &lt;&lt; ' '
     &lt;&lt; std::get&lt;address::country&gt;(t);
  return os;
}

/*We do not need operator&lt; for address as we
  will use the operator&lt; of std::tuple*/

// This is just for testing, real data
// is supplied differently
auto read(std::istream &amp;is)
{
  std::map&lt;std::string, address::type&gt; ret;
  while (is) {
    std::string name;
    address::type addr;
    if (is &gt;&gt; name &gt;&gt; addr) {
      ret[name] = addr;
    }
  }
  return ret;
}
int main()
{
  std::stringstream  ifs(
    &quot;Roger Peckham London UK\n&quot;
    &quot;John Beaconsfield Bucks UK\n&quot;
    &quot;Bart Springfield Illinois USA\n&quot;
    &quot;Michael Chicago Illinois USA\n&quot;
    &quot;Fuzz Oldbury West_Midlands UK\n&quot;
    &quot;Lisa Springfield Illinois USA\n&quot;
    &quot;Thomas Champaign Illinois USA\n&quot;);
  std::map&lt;std::string, address::type&gt; map =
    read(ifs);

  // Don't copy the addresses
  std::vector&lt;address::ref_wrap_const_type&gt;
    addrs;
  for (const auto &amp; entry : map)  {
    addrs.push_back(entry.second);
  }
  for (const auto&amp; v : addrs)  {
    std::cout &lt;&lt; v &lt;&lt; '\n';
  }
  std::cout &lt;&lt;
    &quot;\n---------------------------------\n\n&quot;;
  std::sort(addrs.begin(), addrs.end(),
        [](address::ref_wrap_const_type rwc_a,
           address::ref_wrap_const_type rwc_b)
        {return rwc_a.get() &lt; rwc_b.get();});
  for (const auto&amp; v : addrs) {
    std::cout &lt;&lt; v &lt;&lt; '\n';
  }
  std::cout &lt;&lt; std::flush;
}</pre>

<h3>James Holland</h3>

<p>The student states that the stripped-down example reads data from a file. In fact, it reads data from <code>std::cin</code>. This is a small matter but it means that the end-of-file character has to be entered from the keyboard by pressing the appropriate key. On my system this is Ctrl-D.</p>

<p>Having sorted the input, we can now investigate the processing of the data. The student states that three blank lines are produced. When I ran the program it issued â€œPeckham London UKâ€ on three separate lines. I must confess I am not exactly sure why the program produces this output but it has something to do with declaring the vector <code>addrs</code> with a template parameter of type <code>std::tuple&lt;address &amp;&gt;</code>. Removing the <code>&amp;</code> results in the program working as expected. Now the tuple holds a copy of objects of type <code>address</code>. This is unfortunate as the student wanted to store references to <code>address</code> objects. The way the student has declared the tuple to store references seems perfectly natural but adding the <code>&amp;</code> is incorrect. The correct way to store references is to declare the tuple without the <code>&amp;</code> but to make a tuple from an <code>address</code> object by using <code>std::ref()</code> (declared in the functional header file). This requires an extra line in the <code>for</code>-loop as shown below.</p>

<pre class="programlisting">
  std::vector&lt;std::tuple&lt;address&gt;&gt; addrs;
  for (auto &amp; entry : map)
  {
    auto tup =
      std::make_tuple(std::ref(entry.second));
    addrs.push_back(tup);
  }</pre>
  
<p>I have also made the <code>entry</code> loop variable a reference. This may help speed things up as <code>entry</code> will no longer be a copy of <code>entry.second</code>. The whole tuple is copied, however, when it is pushed onto the back of the vector.</p>

<p>I notice that <code>operator&lt;()</code> has been defined explicitly. There is a slightly neater way of defining <code>operator&lt;()</code> by making use of <code>std::tie()</code> as shown below.</p>

<pre class="programlisting">
  bool operator&lt;(address const &amp; a,
    address const &amp; b)
  {
    return std::tie(a.country, a.county, a.city)
      &lt; std::tie(b.country, b.county, b.city);
  }</pre>
  
<p>In this version of <code>operator&lt;()</code>, the two addresses are first decomposed into the component parts and then reassembled into tuple objects containing three objects: the country, the county and finally the city. When comparing two tuple objects, initially the first parameters of the tuples are compared. If these parameters are equal, the next two parameters are compared, and so on. This is exactly the behaviour that is required for comparing countries, counties, and cities.</p>

<p>As the code uses <code>std::tuple</code>, the header file, <code>#include &lt;tuple&gt;</code>, should be added explicitly. In the studentâ€™s program, I suspect the tuple header file is being found in <code>#include &lt;map&gt;</code>. The second parameter of <code>operator&lt;&lt;()</code> could be made <code>const</code> as could the identifier <code>entry</code> of the first range-based <code>for</code>-loop of <code>main()</code>. There is no need to abbreviate variable names quite so much, I suggest. Perhaps the variable <code>addrs</code> could be renamed <code>addresses_of_candidates</code> or something similar that is appropriate to the application.</p>

<p>The desire to write fast and efficient code is understandable but it is important to, firstly, ensure the code works correctly. Only then is it worth considering modifications that are designed to make the code run faster. Compilers are getting very clever at optimising code for speed and so one should always measure the performance of any code modification to see if it has really made an improvement. I know of cases where an enthusiastic engineer has amended code with the desire of making it faster but has actually made it run slower. It has been said that you should not help the compiler. If you keep things simple the compiler will know what you are trying to do and will probably make a good job at optimising the code. This does not mean that you should not provide the compiler with as much information as possible, however. As an example, making function parameters <code>const ref</code> where appropriate is almost always a good idea.</p>

<p>As the code provided is a stripped-down version of the original application, it is hard to know why particular features have been employed. I am thinking particularly of the use of <code>std::tuple</code>. I can think of no use for a tuple that contains just one value but this may be a result of providing example code that exhibits the problem. Perhaps the code could be designed not use <code>std::tuple</code> thus simplifying things further.</p>

<h3>Marcel MarrÃ© and Jan Eisenhauer</h3>

<p>The main issue of this competitionâ€™s code is the use of references. The original author writes in a comment that he doesnâ€™t want to copy the addresses as he builds the vector to be sorted. However, <code>for (auto entry : map)</code> does exactly that: it makes a copy. Even worse, it makes a temporary copy that is thrown away later, pushing us into the realm of undefined behaviour, which can explain the three empty lines (in my g++ I got three identical lines rather than empty lines; this kind of different behaviour across implementations can indicate undefined behaviour).</p>

<p>However, even after changing the loop to <code>for (auto &amp; entry : map)</code>, all is not well. One entry is duplicated, another gone. The problem is again an incorrect use of references. The original author stores the addresses to be sorted in a <code>std::vector&lt;std::tuple&lt;address&amp;&gt;&gt;</code>. The page on <code>std::sort</code> on cppreference, <a href="https://en.cppreference.com/w/cpp/algorithm/sort">https://en.cppreference.com/w/cpp/algorithm/sort</a>, notes that the iterators must be ValueSwappable. This, however, does not hold for references. Rather than swapping references in the vector, we change data in the map that the vector entries refer to. In other words, with the <code>std::tuple&lt;address&amp;&gt;</code>, construction has different semantics from assignment.</p>

<p>With <code>std::reference_wrapper</code>, construction and assignment have consistent semantics, rebinding the reference in both cases. Hence, changing the vector to <code>std::vector&lt;std::reference_wrapper &lt;address&gt;&gt;</code> corrects the codeâ€™s behaviour.</p>

<p>Following the rule of being as <code>const</code> as possible, we can also declare the output operator as <code>std::ostream&amp; operator&lt;&lt;(std::ostream &amp; os, address const &amp; t)</code> with the body remaining unchanged. This also goes for the output loop: <code>for (auto const &amp; v : addrs)</code>.</p>

<p>While this fixes the behaviour of the code, the <code>operator&lt; </code>can also be written a lot more elegantly in modern C++:</p>

<pre class="programlisting">
  return std::tie(a.country, a.county, a.city)
    &lt; std::tie(b.country, b.county, b.city);</pre>

<p>is the whole required body of the operator, which is immensely more readable, more easily expanded for further fields and thus also a lot less error-prone.</p>

<p>Even though the <code>read</code> function is only for testing, it can also be abbreviated, because formatted input on a bad stream has no effect:</p>

<pre class="programlisting">
  auto read(std::istream &amp;is)
  {
    std::map&lt;std::string, address&gt; ret;
    std::string name;
    address addr;
    while (is &gt;&gt; name &gt;&gt; addr)
    {
      ret[name] = addr;
    }
    return ret;
  }</pre>
  
<p>This also reuses the capacity of the strings in each iteration of the <code>while</code>-loop rather than constructing a new local string each time.</p>

<p>Finally, the code uses nothing from the <code>&lt;iterator&gt;</code> header, so it is cleaner to remove the include.</p>

<h3>Hans Vredeveld</h3>

<p>When I build (with g++ 7.4.0 on Linux) and execute the program with the same data as the OP, I donâ€™t get three blank lines, but three times the line â€˜Peckham London UKâ€™. It looks like we run into some undefined behaviour.</p>

<p>Before we delve into the main problem, letâ€™s get some small issues out of the way.</p>

<p>The include for <code>tuple</code> is missing.</p>

<p>There is a spurious include of <code>iterator</code>.</p>

<p>Like the function read, the <code>operator&gt;&gt;</code> to read in an address is fine for the testing done here, but it is too simple to handle real data. For example, consider the Dutch city Den Haag in the province Zuid Holland.</p>

<p>The <code>operator&lt;&lt;</code> to output an address, does not modify the address and should take it by <code>const&amp;</code>.</p>

<p>To improve readability, it would be nice to have a class or typedef <code>name_t </code>and write <code>std::map&lt;name_t, address&gt;</code>, instead of writing <code>std::map&lt;std::string, address&gt;</code>.</p>

<p>In <code>main</code>, using <code>map</code> both for the type and for the variable is confusing. I suggest renaming the variable to <code>addr_map</code>.</p>

<p>The first two statements in <code>main</code> can be combined into a single statement that initializes the map on construction with the result of <code>read</code>.</p>

<p>The <code>for</code> loop to print the addresses at the end of <code>main</code> should take an address as <code>const&amp;: for (auto const&amp; v : addrs)</code>.</p>

<p>With the small things out of the way, we can start to look into the main issues with the code. In the following, it is instructive to also look at the content of the address map. Therefore, letâ€™s add the following code snippet to the end of main:</p>

<pre class="programlisting">
  for (auto const&amp; entry : addr_map)
  {
    std::cout &lt;&lt; entry.first &lt;&lt; &quot; -&gt; &quot;
      &lt;&lt; entry.second &lt;&lt; '\n';
  }
  std::cout &lt;&lt; '\n';</pre>
  
<p>This will show the input data sorted on name.</p>

<p>The OP wanted to avoid copying addresses. Unfortunately (s)he forgot that when you donâ€™t explicitly specify the loop variable in a range-based <code>for</code>-loop as reference, it will take the elements of the container by copy. The result is that the vector <code>addrs</code> is filled with references to a local variable that is out of scope by the time we sort the vector. In my test situation, it still contained the data of the last address added.</p>

<p>Making the loop-variable entry a reference, the elements in the vector now reference the elements in the map. Building and executing the program, I now get the output</p>

<pre class="programlisting">
  Beaconsfield Bucks UK
  Chicago Illinois USA
  Chicago Illinois USA

  John -&gt; Beaconsfield Bucks UK
  Michael -&gt; Chicago Illinois USA
  Roger -&gt; Chicago Illinois USA</pre>
  
<p>In other words, by sorting the addresses, we made Roger move in with Michael. A serious breach of data integrity! (Replacing <code>std::sort</code> with <code>std::stable_sort</code>, I was able to let Roger move to Chicago and let John and Michael both move to Peckham. Other implementations of <code>std::sort</code> and <code>std::stable_sort</code> may have John, Michael and Roger move around between Beaconsfield, Chicago and Peckham in other ways.)</p>

<p>To use <code>std::tuple&lt;address&amp;&gt;</code> as an element type for the vector <code>addrs</code> is a clever trick to store references in the vector. Too clever, in my opinion. Also note that we donâ€™t want to change anything in the map when sorting the vector, but that changing the <code>addrs</code>â€™s type to <code>std::vector&lt;std::tuple&lt;address const&amp;&gt;&gt;</code> will not compile. To understand why, we have to delve a little bit into what is happening in <code>std::sort</code>. Whatever actual sorting algorithm is used, <code>std::sort</code> will have to move around the elements in the vector. It can only do this by first moving one or more elements into temporary variables, then move other elements into the free spaces in the vector and finally move the elements from the temporary variables into the (new) free spaces in the vector. For example, say that element 0 and 1 have to be swapped. This will result in something similar to:</p>

<pre class="programlisting">
  auto temp = std::move(addrs[0]); // (1)
  addrs[0] = std::move(addrs[1]);  // (2)
  addrs[1] = std::move(temp);      // (3)</pre>

<p>In (1), we move-construct a temporary variable of type <code>std::tuple&lt;address&amp;&gt;</code>. This will initialize the embedded reference with <code>std::forward&lt;address&amp;&gt;( std::get&lt;0&gt;(addrs[0]))</code>, which, because of reference collapsing, means that the reference is copied. Now both <code>temp</code> and <code>addrs[0]</code> reference the same address object. Next, in (2), we move-assign from <code>addrs[1]</code> to <code>addrs[0]</code>. This assigns <code>std::forward&lt;address&amp;&gt;(get&lt;0&gt;(addrs[1]))</code> to <code>get&lt;0&gt;(addrs[0])</code>. Again, reference collapsing applies, and we have an assignment of one lvalue-reference to another lvalue-reference. This is nothing more than copying the content of the address object referenced by <code>addrs[1]</code> to the address object referenced by <code>addrs[0]</code>. Finally, in (3), like in (2), we copy the content of the address object referenced by <code>temp</code>, which was changed via <code>addrs[0]</code> in (2), to the address object referenced by <code>addrs[1]</code>. As a result, we changed the content of the objects referenced by <code>addrs[0]</code> and <code>addrs[1]</code> to both have the value that the object referenced by <code>addrs[1]</code> had before. Sorting the vector thus modifies the map.</p>

<p>To get the desired behaviour of sorting the vector of addresses, we have to use pointers instead of references in the vector. This will also remove the need to use <code>tuple</code>, and we can also make everything related to the map (and the map itself) <code>const</code>. In the <code>sort</code> statement, we have to add a predicate to sort on the values pointed to instead of the pointers themselves. <code>main</code> now has become</p>

<pre class="programlisting">
  int main()
  {
    std::map&lt;name_t, address&gt; const addr_map
      = read(std::cin);

    // Don't copy the addresses
    std::vector&lt;address const*&gt; addrs;
    for (auto const&amp; entry : addr_map)
    {
      addrs.push_back(&amp;entry.second);
    }

    // sort and print the addresses
    std::sort(addrs.begin(), addrs.end(),
      [](auto a, auto b) { return *a &lt; *b; });
    for (auto const&amp; v : addrs)
    {
      std::cout &lt;&lt; *v &lt;&lt; '\n';
    }
    std::cout &lt;&lt; '\n';
  }</pre>
  
<p>Note that we can also use the algorithms <code>std::transform</code> to fill the vector from the map and <code>std::for_each</code> to print the addresses. This is left as an exercise for the reader.</p>

<h3>Balog PÃ¡l</h3>

<p>
This code looks really interesting. However, before engaging, let me insert the rant I have been pushing back for the last few entries and as I really canâ€™t take it any more. Iostreams. &#9785; Can we say goodbye to them? It is only noise and distraction. If we still have related issues, what is the chance we have not pointed them out 36 times over in the 117 previous entries? Especially the input part that only fills our vector or map â€“ all <code>std::</code> collections have very fine <code>{}</code> initialization, the input(s) should just be created that way. For outputs, Iâ€™d also prefer using some simple framework like catch, those who just read printed code can hopefully understand it without a peek.</p>

<p>Having said that, I ignore the <code>iostream</code> parts of this sample. Ok, except for the missing <code>const</code> in the <code>&lt;&lt;</code>, but that is it. With that eliminated we have just half the code. Not even half, just 4 effective lines. How many problems can we fit in this tiny space?</p>

<p>Certainly my improved version would not compile having the map <code>const</code> as it should beâ€¦ and the series of changes needed just to compile would likely remove the problems too. So letâ€™s go somewhat more conservatively and leave the map mutable. While at it, mark the leading 2 lines for doing â€˜create-then-assignâ€™ instead of just initialize, and naming the map <code>map</code>â€¦ that is legal but not nice in my book.</p>

<p>A collection of references packed into a tuple is interesting to start with. Is that even valid? Letâ€™s put that question aside and for the time being assume it is. We iterate over the map incorrectly. Range-based <code>for</code> without <code>&amp;</code> is suspect and the norm is to have <code>const&amp;</code> there. Otherwise it creates a copy of each item, which works at gimped speed when we just use the value and leads to catastrophic failure if we happen to store the address. Which is our case? Looks like the second: we bind the address to the copy not the original as intended. As a side note, <code>emplace_back</code> is a more fitting call here. Even considering that in modern C++, we get the same code for both because of mandatory copy elimination.</p>

<p>Then we sort the vector. We didnâ€™t pass a compare function, so weâ€™ll need an <code>op&lt;</code> here. Ah, we have it too, just lost between the <code>&lt;&lt; &gt;&gt;</code> noise. It looks bad whichever way you look at it, even with a quick glance. The current canonical form is simple: <code>return tie(lhs.k1, lhs.k2... ) &lt; tie(rhs.k1, rhs.k2... )</code>. Yeah, no kidding. Maybe magical but will surely do what is needed, just arrange the same sequence of keys and no lhs/rhs typos once. If done by hand, then you take key one, return immediately if they are <code>&lt;</code> or <code>&gt;</code>, continue with the next key if neither. We miss the step right on the second line with a bad combination. With some luck, in a yearâ€™s time we can just ask for a defaulted <code>&lt;=&gt;</code> and roll with it.</p>

<p>Messing up the <code>compare</code> function is no small deal either, as we face UB if it breaks the rules of irreflexivity, transitivity and transitivity of equivalence. Iâ€™m too lazy to follow up with the actual data; it might be benign by pure luck but donâ€™t count on it. Some STL implementations have nice instrumentation and might point out a problem for you, but again that is not a thing to rely on: just make sure your function is correct. If in doubt, ask an independent review. Some cases appear unintuitive, i.e. I have had to explain that â€œcomparing doubles with tolerance is NOT legal in a sort function!â€ a few dozen times to the same set of people.</p>

<p>So, we have fixed the vector and the compare function, will we sort well now? Well, sort-of. &#9786; Now it will sort something; the question is, how happy we are with that? As we use references in the vector, <code>sort</code> will swap around the values sitting in the map, slicing them off their original keys. So, we have the map itself ordered: John, Michael, Roger. And the addresses will be sorted too, as Bucks, London, Illinois, associated to the people based on that order. The last two guys may not be particularly enthusiastic about that.</p>

<p>Certainly, it would not be evident from the code that it outputs only the addresses, not bothering with the map yet.</p>

<p>With all problems addressed, itâ€™s time to get back to the initial issue of whether collecting and sorting references, that are after all immutable beings (yeah, a reference is not even an object), is a fair deal or not. I honestly cannot tell for sure. I followed the criteria in the standard and got swamped at â€˜equivalentâ€™, which is inconveniently not defined. We have a nice answer on SO: <a href="https://stackoverflow.com/questions/37142510/can-i-sort-vector-of-tuple-of-references">https://stackoverflow.com/questions/37142510/can-i-sort-vector-of-tuple-of-references</a> where the user Barry is adamant that MoveAssignable this way is not conforming on this last point (formally everything seems valid, as the <code>type_traits</code> functions report <code>true</code>). He may be right. But if â€˜equivalentâ€™ means equality or substitutability, then with references it kinda works in its weird way â€“ as we never observe the ref itself just the object behind it. As long as they all look at a distinct object.</p>

<p>Interesting that Barry pointed out <code>sort</code> as bad, but if it is, similar requirement break happens on the vector too.</p>

<p>I pass this mystery over to Roger who will hopefully go into detail on both how to interpret the situation and why it is not clear from the standard text â€“ we might get a core issue here, or at least an editorial addition of a note to shorten the search for the next time</p>

<h2>Commentary</h2>

<p>This code is an example of someone knowing just enough to be dangerous. The most â€˜interestingâ€™ line is the declaration of <code>addrs</code>:</p>

<pre class="programlisting">
  std::vector&lt;std::tuple&lt;address&amp;&gt;&gt; addrs;</pre>
  
<p><em>Why</em> did they use a tuple with a single element? As Nicolas correctly stated, itâ€™s because you canâ€™t create a vector of referencesâ€¦ but by wrapping the reference in a tuple you <em>can</em>. This critique partly answers the question of whether you <em>should</em>.</p>

<p>As several people commented, <code>std::reference_wrapper</code> is designed for this purpose: it wraps a reference in a copyable and assignable object. (Note that while Jamesâ€™s solution correctly creates a <code>reference_wrapper</code> object by using <code>std::ref</code>, but as it is then immediately used to construct a copy the reference nature is not retained.)</p>

<p>References in C++ are quite tricky â€“ they are, to a certain extent, â€˜invisibleâ€™ as you canâ€™t really access a reference, it acts as what can best be described as an alias for an existing object.</p>

<p>So given <code>a</code> and <code>b</code> of type <code>int&amp;</code> the expression a = b simply does an assignment of the referenced objects; and if the type of both changes to <code>std::tuple&lt;int&amp;&gt;</code>, the assignment still assigns the referenced objects.</p>

<p>While references, and tuples of references, comply with the <em>syntax</em> of MoveAssignable (and <code>std::is_move_assignable_v&lt;&gt; </code>will be <code>true</code>), they do nt comply with the expected <em>semantics</em>.</p>

<p>Generally, <code>const</code> references are relatively safe (as long as the lifetime of the referenced object outlasts the reference) but non-<code>const</code> references can be troublesome, especially as member data whether directly or, as in this case, indirectly via a template argument.</p>

<p>Finally, PÃ¡lâ€™s diatribe against iostream is partly answered, at least for output, by the merge of <code>std::format</code> into the working paper for C++20 at the recent WG21 meeting in Cologne. See <a href="http://wg21.link/P0645">http://wg21.link/P0645</a> for the formal wording. (Weâ€™ve also had several informal mentions of this in recent articles in <em>Overload</em>/<em>CVu</em>.)</p>

<h2>The winner of CC 118</h2>

<p>All the entrants successfully resolved the presenting problem. Several also noted that, for code that tried hard to avoid copies by using a â€˜trickâ€™ with a tuple, the range-<code>for</code> loop was <em>copying</em> each element. Marcel and Jan also noted that hoisting the strings <code>name</code> and <code>address</code> out of the loop in the <code>read</code> function would be a small performance win.</p>

<p>I like Hansâ€™ step-by-step explanation of what actually breaks when sorting the collection of references; I hope this explanation would make it clearer to the programmer not only what they had done wrong but why the results were what they were!</p>

<p>The implementation of <code>operator&lt;</code> received some comments â€“ you have to read it quite carefully to check whether it is correct. It does seem that the message about using <code>std::tie</code> to implement these methods is getting heard as almost all the solutions removed the hand-crafted code.</p>

<p>There were good answers from all entrant, but in my opinion, Nicolas wins, by a short head!</p>

<h2>Code Critique 119</h2>

<p>(Submissions to scc@accu.org by October 1st)</p>

<p class="blockquote">Iâ€™m relatively new to C++ and Iâ€™m trying to build up a simple hierarchy of different entities, where their name and id and a few more characteristics are held in an <code>Entity</code> base class; and specific subclasses, such as <code>Widget</code> in the code below, hold the more specialised data â€“ in this case simulated by the member name <code>data</code>. Iâ€™ve been having problems with the program Iâ€™m writing crashing and so Iâ€™ve simplified it down to a short example which usually produces output like this:</p>

<pre class="programlisting">
     Test
     none
     Another widget
     &lt;core dump&gt;</pre>
	 
<p class="blockquote">Please can you suggest what might be causing the core dump? Iâ€™ve had to use <code>-fpermissive</code> with gcc (but not msvc) â€“ but surely thatâ€™s not causing the problem?</p>

<p>Listing 2 contains <span class="Filename">Entity.h</span>, Listing 3 is <span class="Filename">Widget.h</span> and Listing 4 is <span class="Filename">example.cpp</span>. As always, there are a number of other things you might want to draw to the authorâ€™s attention as well as the presenting problem.</p>

<table class="sidebartable">
	<tr>
		<td>
			<pre class="programlisting">
#pragma once
class Entity
{
private: 
  char* pName{ NULL }; 
  int idNumber{ 0 };

public:
  void Setup(char const* name)
  {
    pName = strdup(name);
  }

  virtual ~Entity()
  {
    delete pName;
  }

  // Delete the current object using the dtor,
  // and re-create as a blank object
  void Reset()
  {
    this-&gt;~Entity();
    new(this) Entity();
  }

  char *Name() 
  {
    return pName ? pName : &quot;none&quot;;
  }
};
			</pre>
		</td>
	</tr>
	<tr>
		<td class="title">Listing 2</td>
	</tr>
</table>

<table class="sidebartable">
	<tr>
		<td>
			<pre class="programlisting">
#pragma once
class Widget : public Entity
{
  int* data;
public:
  Widget() { data = new int[10]; }
  ~Widget() { delete data; }
};
			</pre>
		</td>
	</tr>
	<tr>
		<td class="title">Listing 3</td>
	</tr>
</table>

<table class="sidebartable">
	<tr>
		<td>
			<pre class="programlisting">
#include &lt;iostream&gt;
#include &lt;memory&gt;
#include &lt;string.h&gt;

#include &quot;Entity.h&quot;
#include &quot;Widget.h&quot;

int main()
{
  Widget w;
  w.Setup(&quot;Test&quot;);
  std::cout &lt;&lt; w.Name() &lt;&lt; '\n';
  w.Reset();
  std::cout &lt;&lt; w.Name() &lt;&lt; '\n';
  w.Setup(&quot;Another widget&quot;);
  std::cout &lt;&lt; w.Name() &lt;&lt; '\n';
}  
			</pre>
		</td>
	</tr>
	<tr>
		<td class="title">Listing 4</td>
	</tr>
</table>

<p>You can also get the current problem from the accu-general mail list (next entry is posted around the last issueâ€™s deadline) or from the ACCU website (<a href="http://accu.org/index.php/journal">http://accu.org/index.php/journal</a>). This particularly helps overseas members who typically get the magazine much later than members in the UK and Europe.</p>

<p class="bio"><span class="author"><b>Roger Orr</b></span> Roger has been programming for over 20 years, most recently in C++ and Java for various investment banks in Canary Wharf and the City. He joined ACCU in 1999 and the BSI C++ panel in 2002.</p>
</p>
<p><strong>Notes:</strong>&nbsp;</p>
<p><em>More fields may be available via dynamicdata ..</em></p>
</div>
</channel>
</rss>
