<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 283: std::replace() requirement incorrect/insufficient</title>
<meta property="og:title" content="Issue 283: std::replace() requirement incorrect/insufficient">
<meta property="og:description" content="C++ library issue. Status: CD1">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue283.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="283"><a href="lwg-defects.html#283">283</a>. std::replace() requirement incorrect/insufficient</h3>
<p><b>Section:</b> 26.7.5 <a href="https://wg21.link/alg.replace">[alg.replace]</a> <b>Status:</b> <a href="lwg-active.html#CD1">CD1</a>
 <b>Submitter:</b> Martin Sebor <b>Opened:</b> 2000-12-15 <b>Last modified:</b> 2016-01-28</p>
<p><b>Priority: </b>Not Prioritized
</p>
<p><b>View all other</b> <a href="lwg-index.html#alg.replace">issues</a> in [alg.replace].</p>
<p><b>View all issues with</b> <a href="lwg-status.html#CD1">CD1</a> status.</p>
<p><b>Duplicate of:</b> <a href="lwg-closed.html#483" title="Heterogeneous equality and EqualityComparable (Status: Dup)">483</a></p>
<p><b>Discussion:</b></p>
<p>
(revision of the further discussion)
There are a number of problems with the requires clauses for the
algorithms in 25.1 and 25.2. The requires clause of each algorithm
should describe the necessary and sufficient requirements on the inputs
to the algorithm such that the algorithm compiles and runs properly.
Many of the requires clauses fail to do this. Here is a summary of the kinds
of mistakes:
</p>

<ol>
<li>
Use of EqualityComparable, which only puts requirements on a single
type, when in fact an equality operator is required between two
different types, typically either T and the iterator's value type
or between the value types of two different iterators.
</li>
<li>
Use of Assignable for T when in fact what was needed is Assignable
for the value_type of the iterator, and convertability from T to the
value_type of the iterator. Or for output iterators, the requirement
should be that T is writable to the iterator (output iterators do
not have value types).
</li>
</ol>

<p>
Here is the list of algorithms that contain mistakes:
</p>

<ul>
<li>25.1.2 std::find</li>
<li>25.1.6 std::count</li>
<li>25.1.8 std::equal</li>
<li>25.1.9 std::search, std::search_n</li>
<li>25.2.4 std::replace, std::replace_copy</li>
<li>25.2.5 std::fill</li>
<li>25.2.7 std::remove, std::remove_copy</li>
</ul>

<p>
Also, in the requirements for EqualityComparable, the requirement that
the operator be defined for const objects is lacking.
</p>



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

<p>20.1.1 Change p1 from</p>

<p>In Table 28, <code>T</code> is a type to be supplied by a C++ program
instantiating a template, <code>a</code>, <code>b</code>, and <code>c</code> are
values of type <code>T</code>.
</p>

<p>to</p>

<p>
In Table 28, <code>T</code> is a type to be supplied by a C++ program
instantiating a template, <code>a</code>, <code>b</code>, and <code>c</code> are
values of type <code>const T</code>.
</p>

<p>25 Between p8 and p9</p>

<p>Add the following sentence:</p>

<p>When the description of an algorithm gives an expression such as
<code>*first == value</code> for a condition, it is required that the expression
evaluate to either true or false in boolean contexts.</p>

<p>25.1.2 Change p1 by deleting the requires clause.</p>

<p>25.1.6 Change p1 by deleting the requires clause.</p>

<p>25.1.9</p>

<p>Change p4 from</p>

<p>-4- Requires: Type <code>T</code> is <code>EqualityComparable</code>
(20.1.1), type Size is convertible to integral type (4.7.12.3).
</p>

<p>to</p>

<p>-4- Requires: The type <code>Size</code> is convertible to integral
type (4.7.12.3).</p>

<p>25.2.4 Change p1 from</p>

<p>-1- Requires: Type <code>T</code> is <code>Assignable</code> (23.1 ) (and, for <code>replace()</code>, <code>EqualityComparable</code> (20.1.1 )).</p>

<p>to</p>

<p>-1- Requires: The expression <code>*first = new_value</code> must be valid.</p>

<p>and change p4 from</p>

<p>-4- Requires: Type <code>T</code> is <code>Assignable</code> (23.1) (and,
for <code>replace_copy()</code>, <code>EqualityComparable</code>
(20.1.1)). The ranges <code>[first, last)</code> and <code>[result, result +
(last - first))</code> shall not overlap.</p>

<p>to</p>

<p>-4- Requires: The results of the expressions <code>*first</code> and
<code>new_value</code> must be writable to the result output iterator. The
ranges <code>[first, last)</code> and <code>[result, result + (last -
first))</code> shall not overlap.</p>


<p>25.2.5 Change p1 from</p>

<p>-1- Requires: Type <code>T</code> is <code>Assignable</code> (23.1). The
type <code>Size</code> is convertible to an integral type (4.7.12.3).</p>

<p>to</p>

<p>-1- Requires: The expression <code>value</code> must be is writable to
the output iterator. The type <code>Size</code> is convertible to an
integral type (4.7.12.3).</p>

<p>25.2.7 Change p1 from</p>

<p>-1- Requires: Type <code>T</code> is <code>EqualityComparable</code> (20.1.1).</p>

<p>to</p>

<p>
-1- Requires: The value type of the iterator must be
<code>Assignable</code> (23.1).
</p>



<p><b>Rationale:</b></p>
<p>
The general idea of the proposed solution is to remove the faulty
requires clauses and let the returns and effects clauses speak for
themselves. That is, the returns clauses contain expressions that must
be valid, and therefore already imply the correct requirements. In
addition, a sentence is added at the beginning of chapter 25 saying
that expressions given as conditions must evaluate to true or false in
a boolean context. An alternative would be to say that the type of
these condition expressions must be literally bool, but that would be
imposing a greater restriction that what the standard currently says
(which is convertible to bool).
</p>





</body>
</html>
