    <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 104</title>
        <link>https://members.accu.org/index.php/articles/2352</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 29, #1 - March 2017</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/c371/">291</a>
<br />

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

                    -                        <a href="https://members.accu.org/index.php/articles/c183+371/">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 104</h1>
<p><strong>Author:</strong>&nbsp;Martin Moene</p>
<p>
<strong>Date:</strong> 03 March 2017 18:30:29 +00:00 or Fri, 03 March 2017 18:30:29 +00: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 am trying to keep track of a set of peopleâ€™s scores at a game and print out the highest scores in order at the end: it seems to work most of the time but occasionally odd things happen...</p>

<p class="blockquote">Can you see whatâ€™s wrong?</p>

<p>The code â€“ scores.cpp â€“ is in Listing 1.</p>

<table class="sidebartable">
	<tr>
		<td>
			<pre class="programlisting">
#include &lt;functional&gt;
#include &lt;iostream&gt;
#include &lt;map&gt;
#include &lt;sstream&gt;
#include &lt;unordered_map&gt;

// Best scores
std::multimap&lt;int, std::string, std::less&lt;&gt;&gt; best_scores;

// Map people to their best score so far
std::multimap&lt;int, std::string&gt;::iterator typedef entry;
std::unordered_map&lt;std::string, entry&gt; peoples_scores;
entry none;
void add_score(std::string name, int score)
{
  entry&amp; current = peoples_scores[name];
  if (current != none)
  {
     if (score &lt;= current-&gt;first)
     {
       return; // retain the best score
     }
     best_scores.erase(current);
  }
  current = best_scores.insert({score, name});
}
void print_scores()
{
   // top down
   for (auto it = best_scores.end();
        it-- != best_scores.begin(); )
   {
      std::cout &lt;&lt; it-&gt;second &lt;&lt; &quot;: &quot;
        &lt;&lt; it-&gt;first &lt;&lt; '\n';
   }
}
int main()
{
  for (;;)
  {
    std::cout &lt;&lt; &quot;Enter name and score: &quot;;
    std::string lbufr;
    if (!std::getline(std::cin, lbufr)) break;
    std::string name;
    int score;
    std::istringstream(lbufr)
      &gt;&gt; name &gt;&gt; score;
    add_score(name, score);
  }
  std::cout &lt;&lt; &quot;\nBest scores\n&quot;;
  print_scores();
}
			</pre>
		</td>
	</tr>
	<tr>
		<td class="title">Listing 1</td>
	</tr>
</table>

<h2>Critique</h2>

<h3>Chris Main</h3>

<p>This is a tricky problem as I havenâ€™t been able to come up with any valid test data that makes â€˜odd things happenâ€™ on my platform, which is:</p>

<p style="margin-left:1em">g++ 5.4 on Ubuntu 16.04, compiling with -std=c++11.</p>

<p>My first point is therefore the importance of a precise statement of the issue. Ideally this should state the actual input, the expected result and the actual result. Even if this is not possible because the issue cannot be repeatedly reproduced, the description should at least state the kind of issue, for example:</p>

<ul>
	<li>the program crashes</li>
	<li>the program outputs spurious values</li>
	<li>the program outputs incorrect values</li>
	<li>the program outputs lines in the wrong order</li>
	<li>the program does not output as many lines as it should</li>
</ul>

<p>Compilation failed for me because of the <code>std::less&lt;&gt;</code> in the declaration of <code>best_scores</code>. This can be fixed by changing it to <code>std::less&lt;int&gt;</code>, or better still by removing it altogether as that is the default. I assume this was just a typo.</p>

<p>There is no validation of input lines, so if something other than a name and a score is entered that might cause strange results, but the way the question is posed suggests that the problem is less obvious than that.</p>

<p>My first thought was iterator invalidation. Multimap iterators are being held as the <code>mapped_type</code> in an <code>unordered_map</code>. These iterators are associated with entries in <code>best_scores</code>, so I wondered whether they could become invalid when other entries are added to or removed from <code>best_scores</code>. However, after some research I found that multimap iterators are not invalidated in these cases.</p>

<p>In <code>add_score()</code>, the test for whether a person has a previous score is done by calling <code>operator[]</code> and comparing the result with a default constructed iterator. Although this works, it is more idiomatic to call <code>find()</code> and compare the result with the <code>end()</code> iterator. The function would then look like:</p>

<pre class="programlisting">
  auto current = peoples_scores.find(name);
  if (current == peoples_scores.end())
  {
    peoples_scores.insert({name, 
      best_scores.insert({score, name})});
  }
  else if (current-&gt;second-&gt;first &lt; score)
  {
    best_scores.erase(current-&gt;second);
    current-&gt;second =
      best_scores.insert({score, name});
  }</pre>
  
<p>I donâ€™t think this makes any functional difference to the implementation.</p>

<p>In <code>print_scores()</code>, the <code>for</code> loop is not idiomatic, and this is where I think the problem may be. <code>best_scores</code> needs to be iterated in reverse order. The correct way to do this is to use the reverse iterators from begin to end, and in fact the <code>const</code> versions of these can be used:</p>

<pre class="programlisting">
  const auto end_it = best_scores.crend();
  for (auto it = best_scores.crbegin();
     it != end_it;
     ++it)
  {
    std::cout &lt;&lt; it-&gt;second &lt;&lt; &quot;: &quot;
      &lt;&lt; it-&gt;first &lt;&lt; '\n';
  }</pre>
  
<p>There is no range based <code>for</code> loop for reverse iterators in the C++ language itself yet. With a bit of refactoring, <code>std::for_each</code> could be used instead:</p>

<pre class="programlisting">
  #include &lt;algorithm&gt;
  struct output_score
  {
    void operator()(
      const std::pair&lt;int, std::string&gt;&amp; score)
    {
      std::cout &lt;&lt; score.second &lt;&lt; &quot;: &quot;
        &lt;&lt; score.first &lt;&lt; '\n';
    }
  };
  void print_scores()
  {
    std::for_each(best_scores.crbegin(),
            best_scores.crend(),
            output_score());
  }</pre>
  
<p>The original implementation uses forward iterators from end to begin, with a post decrement in the condition. As observed, this does in fact work, but there is a potential problem with the terminating step of the loop. This decrements the iterator to a position before <code>best_scores.begin()</code>, which does not exist, and technically this is undefined behaviour. Because the iterator is never dereferenced when it reaches this invalid position, I expect you would usually get away with this implementation, but maybe this is the cause of â€œoccasionally odd things happen ...â€. I havenâ€™t been able to find anything else.</p>

<h3>James Holland</h3>

<p>It may be the case that the studentâ€™s code runs without error on a particular system. This would be unfortunate as there are two features of the program that rely on undefined behaviour. The program may well fail on other platforms. The first feature that results in undefined behaviour is located in <code>add_score()</code> and is the comparison of default-constructed iterators. One iterator is created by <code>operator[]()</code> belonging to <code>peoples_scores</code>. The other is the global <code>none</code>.</p>

<p>The fact that the standard does not permit the comparison of default constructed iterators is a pity as it renders invalid what would otherwise be a perfectly good function. Perhaps later versions of the standard will permit such comparisons. I could not think of a reasonable way of modifying the studentâ€™s code while still employing <code>operator[]()</code>. Instead, I adopted a fairly straightforward approach that first searches <code>peoples_scores</code> for a record with a key of name and then adds a record or modifies the existing record accordingly.</p>

<p>The second undefined feature is located in <code>print_scores()</code> and results in an iterator pointing to one element before the start of <code>best_scores</code>. This is also not permitted under the standard. Probably the simplest way of resolving this problem is to rewrite the loop using a range-based <code>for</code> loop. The original loop was designed to print <code>best_scores</code> starting with the last record. The range-based <code>for</code> loop can only iterate through the container starting from the first record. The desired result can be obtained by storing the elements of <code>best_scores</code> with the greatest key value at the start of the container. This is achieved by changing the third template parameter of the <code>best_scores</code> type to <code>std::greater&lt;int&gt;</code>. The best scores will now be printed starting with the highest value.</p>

<p>One slight deficiency with the program that still exists is that peopleâ€™s names are stored twice; once in <code>peoples_scores</code> and once in <code>best_scores</code>. It would be more efficient for <code>best_scores</code> to refer the names already stored in <code>peoples_scores</code>. This is a little fiddly to achieve and I do not attempt the modification here.</p>

<p>Finally, I present my version of the studentâ€™s code below.</p>

<pre class="programlisting">
  #include &lt;iostream&gt;
  #include &lt;map&gt;
  #include &lt;sstream&gt;
  #include &lt;unordered_map&gt;
  using best_scores_type = std::multimap&lt;
    const int, const std::string,
     std::greater&lt;int&gt;&gt;;
  best_scores_type best_scores;
  std::unordered_map&lt;std::string,
    best_scores_type::const_iterator&gt;
    peoples_scores;
  void add_score(const std::string &amp; name,
    const int score)
  {
    const auto people_position =
      peoples_scores.find(name);
    if (people_position != peoples_scores.end())
    {
      if (score &gt; people_position-&gt;
                    second-&gt;first)
      {
        best_scores.erase(
          people_position-&gt;second);
        people_position-&gt;second =
          best_scores.insert({score, name});
      }
    }
    else
    {
      const auto best_scores_position =
        best_scores.insert({score, name});
      peoples_scores.insert({name,
        best_scores_position});
    }
  }
  void print_scores()
  {
    for (const auto &amp; person : best_scores)
    {
      std::cout &lt;&lt; person.second &lt;&lt; &quot;: &quot;
        &lt;&lt; person.first &lt;&lt; '\n';
    }
  }
  int main()
  {
    for (;;)
    {
      std::cout &lt;&lt; &quot;Enter name and score: &quot;;
      std::string lbufr;
      if (!std::getline(std::cin, lbufr)) break;
      std::string name;
      int score;
      std::istringstream(lbufr) &gt;&gt; name
        &gt;&gt; score;
      add_score(name, score);
    }
    std::cout &lt;&lt; &quot;\nBest scores\n&quot;;
    print_scores();
  }</pre>
  
<h3>Herman Pijl</h3>

<p>Apparently the developer wants to keep track of the high scores and simultaneously maintain a lookup that maps the user to an entry in the high score table.</p>

<p>The <code>print_scores</code> function looks a bit suspicious.</p>

<p>I decide to run the program, and after the prompt appears, I press Ctrl-d to end the input. The result is a segmentation fault (I am running on Cygwin). Iterating over the elements of a container in reverse order should not be an adventure. Just use the reverse iterators that were designed exactly for this purpose (<code>rbegin()</code> and <code>rend()</code>) to avoid problems or even crashes as the one I had.</p>

<p>Reverse iteration doesnâ€™t look natural at first sight. The ordered containers allow to specify an ordering criterion. The default ordering criterion happens to be <code>std::less</code>, but nothing keeps you from using another ordering criterion from the algorithm library, e.g. <code>std::greater</code>. The given code explicitly mentions the default ordering criterion and this explicit (default) choice is probably meant to be a hint to change the program. Ordering from high to low values allows to iterate over the container with the usual <code>begin()</code> and <code>end()</code> boundaries.</p>

<p>Letâ€™s move to the next problem in this code. The <code>peoples_scores</code> map attempts to keep track of the position in the <code>best_scores</code> map. Unfortunately it is not such a good idea to keep a copy of an iterator in a table. Stroustrup (4th Ed. $31.2) mentions that the ordered [multi]map/sets are usually implemented as balanced binary trees (mostly red-black trees). To keep such a tree balanced (and therefore performant O(log(n))) some pruning is needed causing the traversal (=iteration) to be different after insertions/deletions. </p>

<p>So if you cannot use an iterator, then what can you use? Remarkably the answer is: a pointer! There is no such thing as a commandment that says: â€œThou shalt not use pointers!â€ Some people try to avoid them dogmatically, but sometimes you have no choice.</p>

<p>The standard library does this too in some cases, e.g. when you construct an <code>istream_iterator</code>, you typically pass an <code>istream</code> to the constructor as reference, BUT the <code>istream</code> iterator takes the address of that <code>istream</code> (thus a pointer) and it keeps that as a private member. One of the good reasons to keep a pointer is that the <code>istream_iterator</code> is an input iterator ($33.1.2) and as such it has to be copyable.</p>

<p>I am going to keep the <code>const_pointer</code> type of the multimap, i.e. <code>std::multimap&lt;int, std::string&gt;::const_pointer</code> will become my entry type.</p>

<p>The <code>value_type</code> of a map is typically a (K, V) pair.</p>

<p>I assume that the standard allocator will allocate the nodes on the heap, so that the addresses of the <code>value_type</code> will not change when a red-black tree gets reorganised.</p>

<p>The <code>best_scores</code> and <code>peoples_scores</code> maps have to be maintained â€˜transactionallyâ€™, so that there is always exactly one entry in both for a particular user.</p>

<p>In order to add an entry to the <code>best_scores</code> map, I use the <code>emplace</code> method. As it returns an iterator, I deference it and use the address-of operator to find my <code>const_pointer</code>:</p>

<pre class="programlisting">
  &amp;*best_scores.emplace(score, name);</pre>
  
<p>When there is no entry for the user I can just do:</p>

<pre class="programlisting">
  peoples_scores.emplace(name,
    &amp;*best_scores.emplace(score, name));</pre>
	
<p>When there is already an entry for the user, then I have to check whether the score is better than the previous score. If that is the case, then I have to erase the previous score. Unfortunately, multiple users can have the same score. So in order to find the right entry and erase it I use</p>

<pre class="programlisting">
  // bs is reference to best_scores
  bs.erase(std::find_if(
    bs.lower_bound(prevScore),
    bs.upper_bound(prevScore),
    [&amp;](auto &amp; it)-&gt; bool{
      return it.second == name;
  }));</pre>
  
<p>After that I need to add a new entry in the <code>best_scores</code> table and update the reference to it in the <code>peoples_scores</code> map.</p>

<pre class="programlisting">
  itFind-&gt;second = &amp;*bs.emplace(score, name);</pre>
  
<p>It seems to work fine.</p>

<p>Further enhancements could be the introduction of a good old fashioned struct containing name and score and defining the extraction operator <code>&gt;&gt; </code>on it so that so that you can write the processing as a <code>for_each</code> call.</p>

<p>A complete solution is shown below:</p>

<pre class="programlisting">
  #include &lt;functional&gt;
  #include &lt;iostream&gt;
  #include &lt;map&gt;
  #include &lt;sstream&gt;
  #include &lt;unordered_map&gt;
  // added
  #include &lt;algorithm&gt;
  #include &lt;cassert&gt;
  #include &lt;iterator&gt;
  // Best scores
  /*added*/
 std::multimap&lt;int, std::string,
    std::less&lt;&gt;&gt; typedef best_scores_type;
  std::multimap&lt;int, std::string,
    std::less&lt;&gt;&gt; best_scores;
  auto &amp; bs = best_scores;
  // new unordered map
  std::unordered_map&lt;std::string, 
    best_scores_type::const_pointer&gt; 
    nps; //new_peoples_scores

  void new_add_score(std::string name,
    int score)
  {
    auto itFind = nps.find(name);
    if (itFind != nps.end()){
      // player already present
      int prevScore = itFind-&gt;second-&gt;first; 
      if (prevScore &lt; score){
        bs.erase(std::find_if(
          bs.lower_bound(prevScore),
          bs.upper_bound(prevScore),
          [&amp;](auto &amp; it)-&gt; bool{
            return it.second == name;}));
        itFind-&gt;second =
          &amp;*bs.emplace(score, name);
      }
    } else { // new player

      nps.emplace(name,
        &amp;*bs.emplace(score, name));
    }
  }
  void print_scores()
  {
    std::for_each(best_scores.rbegin(),
      best_scores.rend(),
      [](auto &amp; it){
        std::cout &lt;&lt; it.second &lt;&lt; &quot;: &quot;
          &lt;&lt; it.first &lt;&lt; '\n';});
  }
  struct NameScoreEntry{ std::string name;
    int score; };
  std::istream &amp; operator&gt;&gt;(std::istream&amp; is,
    NameScoreEntry&amp; entry)
  {
    is &gt;&gt; entry.name &gt;&gt; entry.score;
    return is;
  }
  void extract(std::istream &amp; is){
    std::istream_iterator&lt;NameScoreEntry&gt;
      ist(is), eos;
    std::for_each(ist, eos, [&amp;](auto i){
      new_add_score(i.name, i.score);});
  }
  int main(){
    std::cout &lt;&lt;
      &quot;Enter name and score (multiple lines): &quot;;
    extract(std::cin);
    print_scores();
  }</pre>
  
<h2>Commentary</h2>

<p>This is a critique that is principally about undefined behaviour â€“ often abbreviated to UB. There are in fact <em>three</em> different examples of this in the code presented. You might want to stop now and see if you can find them with this hint before reading on!</p>

<p>The first problem is the use of the default-constructed <code>entry</code> object named <code>none</code>. As James noted, the standard does not allow comparisons between default-constructed iterators and so the comparison</p>

<pre class="programlisting">
  if (current != none)</pre>
  
<p>is not valid. As it happens, the code appears to run successfully with a number of combinations of compilers and flags: one of the problems with undefined behaviour is that it can be quite hard to detect.</p>

<p>The second problem is that the loop in <code>print_scores</code> counting backwards through <code>best_scores</code> decrements the iterator <code>it</code> to point <em>before</em> the beginning of the collection. This is also not valid, and may cause runtime failures depending on exactly how <code>multimap</code> is implemented in the standard library being used. Some years ago I encountered a similar problem with code that removed items from a <code>std::list</code> and decremented the iterator referring to the item being removed. This had worked for years with one implementation of the standard library, but when ported to a different environment decrementing the iterator when the item being deleted was at <code>begin()</code> caused failures at runtime.</p>

<p>The third problem is that the <code>typedef</code> for <code>entry</code> is incorrect. It refers to an iterator into a <code>multimap</code> with a defaulted comparator but the actual map has an explicitly specified comparator of <code>std::less&lt;&gt;</code>. This subtle difference means the resultant iterators are of different types and adds some more possibly troubling behaviour.</p>

<p>(Note: <code>std::less&lt;&gt;</code> was added in C++ 14, which is why Chris Main couldnâ€™t compile the code using -std=c++11. It was proposed by Stephan Lavavej and his proposed wording was voted into the standard without needing <em>any</em> editing, which is very unusual!)</p>

<p>There are several ways to attack these problems; but <em>identifying</em> them is often the hardest step. Fortunately, many compilers provide extra validation when using the standard library that can make this easy.</p>

<p>For example, compiling the sample code using gcc and adding the flag <code>-D_GLIBCXX_DEBUG</code> will use an instrumented version of the standard library. The code as presented wonâ€™t even compile with this flag specified because of the mismatched iterator types.</p>

<p>Similar instrumentation is available with MSVC when using the debugging runtime library (eg adding <code>-MDd</code>).</p>

<p>Incidentally, this is another reason to prefer using the standard library to your own hand-written codeâ€¦</p>

<p>As the entries showed, solving the problem caused by trying to use none as a sentinel value can be resolved by the use of <code>find</code> rather than the simple use of the square bracket operator.</p>

<p>The over-enthusiastic decrementing of the iterator can be resolved by using a more idiomatic loop: either by changing the comparator to <code>std::greater&lt;&gt; </code>or by changing the loop to use <code>crbegin</code> and <code>crend</code>. The first option has the additional benefit of allowing use of range-for.</p>

<p>I was expecting someone to comment about the placement of <code>typedef</code> in the middle of the line: placing <code>typedef</code> at the beginning of the line is an extremely common coding convention. In modern C++ code though I would recommend <code>using</code> over <code>typedef</code> as I think it is more readable.</p>

<h2>The winner of CC 103</h2>

<p>I was (deliberately) a little vague in setting the critique about what exactly the symptoms were (â€œoccasionally odd things happenâ€) â€“ perhaps I should have been a little more forthcoming! Unfortunately, of course, when undefined behaviour occurs the symptoms are often just like thisâ€¦</p>

<p>While Chris did not identify the undefined behaviour, his instincts for writing idiomatic code were sound and so his modifications did in fact deal with the two main pieces of UB.</p>

<p>James identified the two main sources of UB and he also, by changing the comparator, was able to change the code in <code>print_scores</code> to use range-for, which makes it clearer.</p>

<p>Herman was very close to identifying the problem; but in fact the iterators are not invalidated when the map is re-balanced. His replacement of iterators with pointers was valid and did have the side-effect of removing the undefined behaviour. I did like his introduction of a simple helper struct <code>NameScoreEntry</code> to assist with reading the data in: it is very easy to create such structs in C++ and there can be significant benefits for readability with having named fields.</p>

<p>Overall, I think James provided the best critique, so I have awarded him the prize.</p>

<h2>Code critique 104</h2>

<p><strong>(Submissions to scc@accu.org by April 1st)</strong></p>

<p class="blockquote">I was trying to write a simple template that gets the unique values from a range of values (rather like the Unix program uniq) but my simple test program throws up a problem.</p>

<pre class="programlisting">
    test with strings
    a a b b c c =&gt; a b c
    test with ints
    1 1 2 2 3 3 =&gt; 1 1 2 3</pre>
	
<p class="blockquote">Why is the duplicate 1 not being removed?</p>

<p>The code is in Listing 2 (unique.h) and Listing 3 (unique.cpp).</p>

<table class="sidebartable">
	<tr>
		<td>
			<pre class="programlisting">
#include &lt;iterator&gt;
#include &lt;vector&gt;
// get unique values in the range [one, two)
template &lt;typename iterator&gt;
std::vector&lt;typename iterator::value_type&gt;
unique(iterator one, iterator two)
{
  if (distance(one, two) &lt; 2)
  {
    // no duplicates
    return {one, two};
  }
  // first one can't be a duplicate
  std::vector&lt;typename iterator::value_type&gt;
  result{1, *one};
  while (++one != two)
  {
    auto next = *one;
    bool is_unique =
     (*result.rbegin() != next);
    if (is_unique)
    {
       result.push_back(next);
    }
  }
  return result;
}
			</pre>
		</td>
	</tr>
	<tr>
		<td class="title">Listing 2</td>
	</tr>
</table>

<table class="sidebartable">
	<tr>
		<td>
			<pre class="programlisting">
#include &lt;iostream&gt;
#include &lt;string&gt;
#include &lt;vector&gt;
#include &quot;unique.h&quot;
template &lt;typename T&gt;
void test(std::ostream &amp;os,
  std::vector&lt;T&gt; const &amp;vector)
{
   auto result =
     unique(vector.begin(), vector.end());
   auto out =
     std::ostream_iterator&lt;T&gt;(os, &quot; &quot;);
   copy(vector.begin(), vector.end(), out);
   os &lt;&lt; &quot;=&gt; &quot;;
   copy(result.begin(), result.end(), out);
   os &lt;&lt; &quot;\n&quot;;
}
int main()
{
   std::cout &lt;&lt; &quot;test with strings\n&quot;;
   std::vector&lt;std::string&gt; ptrs;
   ptrs.push_back(&quot;a&quot;);
   ptrs.push_back(&quot;a&quot;);
   ptrs.push_back(&quot;b&quot;);
   ptrs.push_back(&quot;b&quot;);
   ptrs.push_back(&quot;c&quot;);
   ptrs.push_back(&quot;c&quot;);
   test(std::cout, ptrs);
   
   std::cout &lt;&lt; &quot;test with ints\n&quot;;
   std::vector&lt;int&gt; ints;
   ints.push_back(1);
   ints.push_back(1);
   ints.push_back(2);
   ints.push_back(2);
   ints.push_back(3);
   ints.push_back(3);
   test(std::cout, ints);
}	 
			</pre>
		</td>
	</tr>
	<tr>
		<td class="title">Listing 3</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>
<p><strong>Notes:</strong>&nbsp;</p>
<p><em>More fields may be available via dynamicdata ..</em></p>
</div>
</channel>
</rss>
