<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 92: Incomplete Algorithm Requirements</title>
<meta property="og:title" content="Issue 92: Incomplete Algorithm Requirements">
<meta property="og:description" content="C++ library issue. Status: CD1">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue92.html">
<meta property="og:type" content="website">
<meta property="og:image" content="http://cplusplus.github.io/LWG/images/cpp_logo.png">
<meta property="og:image:alt" content="C++ logo">
<style>
  p {text-align:justify}
  li {text-align:justify}
  pre code.backtick::before { content: "`" }
  pre code.backtick::after { content: "`" }
  blockquote.note
  {
    background-color:#E0E0E0;
    padding-left: 15px;
    padding-right: 15px;
    padding-top: 1px;
    padding-bottom: 1px;
  }
  ins {background-color:#A0FFA0}
  del {background-color:#FFA0A0}
  table.issues-index { border: 1px solid; border-collapse: collapse; }
  table.issues-index th { text-align: center; padding: 4px; border: 1px solid; }
  table.issues-index td { padding: 4px; border: 1px solid; }
  table.issues-index td:nth-child(1) { text-align: right; }
  table.issues-index td:nth-child(2) { text-align: left; }
  table.issues-index td:nth-child(3) { text-align: left; }
  table.issues-index td:nth-child(4) { text-align: left; }
  table.issues-index td:nth-child(5) { text-align: center; }
  table.issues-index td:nth-child(6) { text-align: center; }
  table.issues-index td:nth-child(7) { text-align: left; }
  table.issues-index td:nth-child(5) span.no-pr { color: red; }
  @media (prefers-color-scheme: dark) {
     html {
        color: #ddd;
        background-color: black;
     }
     ins {
        background-color: #225522
     }
     del {
        background-color: #662222
     }
     a {
        color: #6af
     }
     a:visited {
        color: #6af
     }
     blockquote.note
     {
        background-color: rgba(255, 255, 255, .10)
     }
  }
</style>
</head>
<body>
<hr>
<p><em>This page is a snapshot from the LWG issues list, see the <a href="lwg-active.html">Library Active Issues List</a> for more information and the meaning of <a href="lwg-active.html#CD1">CD1</a> status.</em></p>
<h3 id="92"><a href="lwg-defects.html#92">92</a>. Incomplete Algorithm Requirements</h3>
<p><b>Section:</b> 26 <a href="https://wg21.link/algorithms">[algorithms]</a> <b>Status:</b> <a href="lwg-active.html#CD1">CD1</a>
 <b>Submitter:</b> Nico Josuttis <b>Opened:</b> 1998-09-29 <b>Last modified:</b> 2016-01-28</p>
<p><b>Priority: </b>Not Prioritized
</p>
<p><b>View other</b> <a href="lwg-index-open.html#algorithms">active issues</a> in [algorithms].</p>
<p><b>View all other</b> <a href="lwg-index.html#algorithms">issues</a> in [algorithms].</p>
<p><b>View all issues with</b> <a href="lwg-status.html#CD1">CD1</a> status.</p>
<p><b>Discussion:</b></p>
<p>The standard does not state, how often a function object is copied,
called, or the order of calls inside an algorithm. This may lead to
surprising/buggy behavior. Consider the following example: </p>

<pre>class Nth {    // function object that returns true for the nth element 
  private: 
    int nth;     // element to return true for 
    int count;   // element counter 
  public: 
    Nth (int n) : nth(n), count(0) { 
    } 
    bool operator() (int) { 
        return ++count == nth; 
    } 
}; 
.... 
// remove third element 
    list&lt;int&gt;::iterator pos; 
    pos = remove_if(coll.begin(),coll.end(),  // range 
                    Nth(3)),                  // remove criterion 
    coll.erase(pos,coll.end()); </pre>

<p>This call, in fact removes the 3rd <b>AND the 6th</b> element. This
happens because the usual implementation of the algorithm copies the
function object internally: </p>

<pre>template &lt;class ForwIter, class Predicate&gt; 
ForwIter std::remove_if(ForwIter beg, ForwIter end, Predicate op) 
{ 
    beg = find_if(beg, end, op); 
    if (beg == end) { 
        return beg; 
    } 
    else { 
        ForwIter next = beg; 
        return remove_copy_if(++next, end, beg, op); 
    } 
} </pre>

<p>The algorithm uses find_if() to find the first element that should
be removed. However, it then uses a copy of the passed function object
to process the resulting elements (if any). Here, Nth is used again
and removes also the sixth element. This behavior compromises the
advantage of function objects being able to have a state. Without any
cost it could be avoided (just implement it directly instead of
calling find_if()). </p>


<p id="res-92"><b>Proposed resolution:</b></p>

<p>Add a new paragraph following 26 <a href="https://wg21.link/algorithms">[algorithms]</a> paragraph 8:</p>
<blockquote><p>
[Note: Unless otherwise specified, algorithms that take function
objects as arguments are permitted to copy those function objects
freely.  Programmers for whom object identity is important should
consider using a wrapper class that points to a noncopied
implementation object, or some equivalent solution.]
</p></blockquote>

<p><i>[Dublin: Pete Becker felt that this may not be a defect,
but rather something that programmers need to be educated about.
There was discussion of adding wording to the effect that the number
and order of calls to function objects, including predicates, not
affect the behavior of the function object.]</i></p>


<p><i>[Pre-Kona: Nico comments: It seems the problem is that we don't
have a clear statement of &quot;predicate&quot; in the
standard. People including me seemed to think &quot;a function
returning a Boolean value and being able to be called by an STL
algorithm or be used as sorting criterion or ... is a
predicate&quot;. But a predicate has more requirements: It should
never change its behavior due to a call or being copied. IMHO we have
to state this in the standard. If you like, see section 8.1.4 of my
library book for a detailed discussion.]</i></p>


<p><i>[Kona: Nico will provide wording to the effect that &quot;unless
otherwise specified, the number of copies of and calls to function
objects by algorithms is unspecified&quot;.&nbsp; Consider placing in
26 <a href="https://wg21.link/algorithms">[algorithms]</a> after paragraph 9.]</i></p>


<p><i>[Santa Cruz: The standard doesn't currently guarantee that
  functions object won't be copied, and what isn't forbidden is
  allowed.  It is believed (especially since implementations that were
  written in concert with the standard do make copies of function
  objects) that this was intentional.  Thus, no normative change is
  needed.  What we should put in is a non-normative note suggesting to
  programmers that if they want to guarantee the lack of copying they
  should use something like the <code>ref</code> wrapper.]</i></p>


<p><i>[Oxford: Matt provided wording.]</i></p>








</body>
</html>
