<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 3049: Missing wording allowing algorithms to use copies of function objects as substitutes for their parameters</title>
<meta property="og:title" content="Issue 3049: Missing wording allowing algorithms to use copies of function objects as substitutes for their parameters">
<meta property="og:description" content="C++ library issue. Status: Open">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue3049.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#Open">Open</a> status.</em></p>
<h3 id="3049"><a href="lwg-active.html#3049">3049</a>. Missing wording allowing algorithms to use copies of function objects as substitutes for their parameters</h3>
<p><b>Section:</b> 26.2 <a href="https://wg21.link/algorithms.requirements">[algorithms.requirements]</a> <b>Status:</b> <a href="lwg-active.html#Open">Open</a>
 <b>Submitter:</b> Jared Hoberock <b>Opened:</b> 2017-12-04 <b>Last modified:</b> 2022-04-25</p>
<p><b>Priority: </b>3
</p>
<p><b>View other</b> <a href="lwg-index-open.html#algorithms.requirements">active issues</a> in [algorithms.requirements].</p>
<p><b>View all other</b> <a href="lwg-index.html#algorithms.requirements">issues</a> in [algorithms.requirements].</p>
<p><b>View all issues with</b> <a href="lwg-status.html#Open">Open</a> status.</p>
<p><b>Discussion:</b></p>
<p>
When designing the parallel algorithms library, we intended for parallel algorithms to copy their function objects parameters 
when it is possible and useful to do so, but there doesn't appear to be any wording to enable that latitude. To the contrary, 
algorithm specifications refer to their function object parameters by name, implying that a copy of the parameter may not 
be used as a substitute.
<p/>
This was noticed when Billy O'Neal observed that parallel <code>generate()</code> did not share parallel <code>for_each()</code> and 
<code>for_each_n()</code>'s special requirement for a <code>CopyConstructible</code> user-provided function object.
<p/>
This <code>CopyConstructible Function</code> requirement was added to relax legacy <code>for_each()</code>'s <code>MoveConstructible Function</code>
requirement to allow parallel implementations to make copies as necessary. All parallel algorithms need similar permissions, 
but a strong requirement for <code>CopyConstructible</code> in all algorithms is too restrictive.
<p/>
What we require is to allow algorithm implementations to use copies of function objects as substitutes for their original parameters, 
while not requiring that all function object parameters be copyable.
<p/>
Casey Carter noted that 26.2 <a href="https://wg21.link/algorithms.requirements">[algorithms.requirements]</a> p8 grants permission to all algorithms to copy their function 
object parameters. However, this paragraph is not normative and does not indicate how the algorithm is allowed to use such copies. 
Additionally, it does not specify which algorithm parameters are the ones called out as function objects. For example, 
26.7.7 <a href="https://wg21.link/alg.generate">[alg.generate]</a> refers to <code>gen</code> as a function object, but 26.6.5 <a href="https://wg21.link/alg.foreach">[alg.foreach]</a> does not refer to <code>f</code> 
as a function object. All the other types of callable algorithm parameters (i.e. <code>Predicate</code>, <code>BinaryPredicate</code>, 
<code>Compare</code>, <code>UnaryOperation</code>, <code>BinaryOperation</code>, <code>BinaryOperation1</code>, and <code>BinaryOperation2</code>) 
are defined to be function objects in 26.2 <a href="https://wg21.link/algorithms.requirements">[algorithms.requirements]</a> and 26.3.2 <a href="https://wg21.link/algorithms.parallel.user">[algorithms.parallel.user]</a>. This 
list intentionally omits <code>Function</code> and <code>Generator</code> by design.
<p/>
A potential resolution would introduce normative wording to explicitly allow algorithms to use copies of function object parameters 
as substitutes for their function object parameters, and remove ambiguity in algorithm specifications about which parameters are 
function objects.
</p>
<p><i>[2018-01; Priority set to 3 after mailing list discussion]</i></p>


<p><i>[2018-3-14 Wednesday evening issues processing; move to Open]</i></p>

<p>We thought that the notes in [alg.foreach]/1 and /11 should be unwrapped as well. Bryce to work with Jared on updated wording.</p>

<p>
<strong>Previous resolution [SUPERSEDED]:</strong>
</p>
<blockquote class="note">
<p>
This wording is relative to <a href="https://wg21.link/N4713" title=" Working Draft, Standard for Programming Language C++">N4713</a>.
</p>

<ol>
<li><p>Modify 26.2 <a href="https://wg21.link/algorithms.requirements">[algorithms.requirements]</a> as indicated:</p>

<blockquote>
<p>
-8- <del>[<i>Note:</i></del> Unless otherwise specified, algorithms that take function objects as arguments are permitted to copy
those function objects freely. <ins>When an algorithm's specification requires the invocation of a function object parameter, 
such a copy may be invoked as a substitute for the original function object parameter.</ins> <ins>[<i>Note:</i> This implies 
that copyable user-supplied function objects should not rely on their identity.</ins> Programmers for whom object identity is 
important should consider using a wrapper class that points to a noncopied implementation object such as 
<code>reference_wrapper&lt;T&gt;</code> (22.10.6 <a href="https://wg21.link/refwrap">[refwrap]</a>), or some equivalent solution. &mdash; <i>end note</i>]
</p>
</blockquote>

</li>

<li><p>Modify 26.6.5 <a href="https://wg21.link/alg.foreach">[alg.foreach]</a> as indicated:</p>

<blockquote>
<pre>
template&lt;class InputIterator, class Function&gt;
  constexpr Function for_each(InputIterator first, InputIterator last, Function f);
</pre>
<blockquote>
<p>
[&hellip;]
<p/>
-2- <i>Effects:</i> Applies <ins>the function object</ins> <code>f</code> to the result of dereferencing every iterator in the range 
<code>[first, last)</code>, [&hellip;]
<p/>
[&hellip;]
</p>
</blockquote>
<pre>
template&lt;class ExecutionPolicy, class ForwardIterator, class Function&gt;
  void for_each(ExecutionPolicy&amp;&amp; exec,
                ForwardIterator first, ForwardIterator last,
                Function f);
</pre>
<blockquote>
<p>
<del>-6- <i>Requires:</i> <code>Function</code> shall meet the requirements of <code>CopyConstructible</code>.</del>
<p/>
-7- <i>Effects:</i> Applies <ins>the function object</ins> <code>f</code> to the result of dereferencing every iterator in the range 
<code>[first, last)</code>. [&hellip;]
<p/>
[&hellip;]
</p>
</blockquote>
<pre>
template&lt;class InputIterator, class Size, class Function&gt;
constexpr InputIterator for_each_n(InputIterator first, Size n, Function f);
</pre>
<blockquote>
<p>
[&hellip;]
<p/>
-13- <i>Effects:</i> Applies <ins>the function object</ins> <code>f</code> to the result of dereferencing every iterator in the range 
<code>[first, first + n)</code> in order. [&hellip;]
<p/>
[&hellip;]
</p>
</blockquote>
<pre>
template&lt;class ExecutionPolicy, class ForwardIterator, class Size, class Function&gt;
  ForwardIterator for_each_n(ExecutionPolicy&amp;&amp; exec, ForwardIterator first, Size n,
                             Function f);
</pre>
<blockquote>
<p>
<del>-16- <i>Requires:</i> <code>Function</code> shall meet the requirements of <code>CopyConstructible</code>.</del>
<p/>
[&hellip;]
<p/>
-18- <i>Effects:</i> Applies <ins>the function object</ins> <code>f</code> to the result of dereferencing every iterator in the range 
<code>[first, first + n).</code> [&hellip;]
<p/>
[&hellip;]
</p>
</blockquote>
</blockquote>
</li>
</ol>
</blockquote>

<p><i>[2022-04-25; Daniel rebases wording on <a href="https://wg21.link/N4910" title=" Working Draft, Standard for Programming Language C++">N4910</a>]</i></p>

<p>
The previously refactored note term "can" in 26.2 <a href="https://wg21.link/algorithms.requirements">[algorithms.requirements]</a> p10 has been 
reverted to "permitted" to specify a normative implementation freedom.
</p>

<p><i>[2022-04-25; Daniel comments]</i></p>

<p>
Bryce and Jared have unassigned from this issue.
</p>


<p id="res-3049"><b>Proposed resolution:</b></p>
<p>
This wording is relative to <a href="https://wg21.link/N4910" title=" Working Draft, Standard for Programming Language C++">N4910</a>.
</p>

<ol>
<li><p>Modify 26.2 <a href="https://wg21.link/algorithms.requirements">[algorithms.requirements]</a> as indicated:</p>

<blockquote>
<p>
-10- <del>[<i>Note 2:</i></del> Unless otherwise specified, algorithms that take function objects as arguments 
<del>can</del><ins>are permitted to</ins> copy those function objects freely. <ins>When an algorithm's 
specification requires the invocation of a function object parameter, such a copy may be invoked as a substitute 
for the original function object parameter.
[<i>Note:</i> This implies that copyable user-supplied function objects should not rely on their identity.</ins> 
If object identity is important, a wrapper class that points to a noncopied implementation object such as 
<code>reference_wrapper&lt;T&gt;</code> (22.10.6 <a href="https://wg21.link/refwrap">[refwrap]</a>), or some equivalent solution, can be used. &mdash; 
<i>end note</i>]
</p>
</blockquote>

</li>

<li><p>Modify 26.6.5 <a href="https://wg21.link/alg.foreach">[alg.foreach]</a> as indicated:</p>

<blockquote>
<pre>
template&lt;class InputIterator, class Function&gt;
  constexpr Function for_each(InputIterator first, InputIterator last, Function f);
</pre>
<blockquote>
<p>
[&hellip;]
<p/>
-2- <i>Effects:</i> Applies <ins>the function object</ins> <code>f</code> to the result of dereferencing every iterator in the range 
<code>[first, last)</code>, [&hellip;]
<p/>
[&hellip;]
</p>
</blockquote>
<pre>
template&lt;class ExecutionPolicy, class ForwardIterator, class Function&gt;
  void for_each(ExecutionPolicy&amp;&amp; exec,
                ForwardIterator first, ForwardIterator last,
                Function f);
</pre>
<blockquote>
<p>
<del>-6- <i>Preconditions:</i> <code>Function</code> meets the <i>Cpp17CopyConstructible</i> requirements.</del>
<p/>
-7- <i>Effects:</i> Applies <ins>the function object</ins> <code>f</code> to the result of dereferencing every iterator in the range 
<code>[first, last)</code>. [&hellip;]
<p/>
[&hellip;]
</p>
</blockquote>
<pre>
template&lt;class InputIterator, class Size, class Function&gt;
constexpr InputIterator for_each_n(InputIterator first, Size n, Function f);
</pre>
<blockquote>
<p>
[&hellip;]
<p/>
-18- <i>Effects:</i> Applies <ins>the function object</ins> <code>f</code> to the result of dereferencing every iterator in the range 
<code>[first, first + n)</code> in order. [&hellip;]
<p/>
[&hellip;]
</p>
</blockquote>
<pre>
template&lt;class ExecutionPolicy, class ForwardIterator, class Size, class Function&gt;
  ForwardIterator for_each_n(ExecutionPolicy&amp;&amp; exec, ForwardIterator first, Size n,
                             Function f);
</pre>
<blockquote>
<p>
[&hellip;]
<p/>
-22- <i>Preconditions:</i> <code>n &gt;= 0</code> is <code>true</code>. <del><code>Function</code> meets the 
<code>Cpp17CopyConstructible</code> requirements.</del>
<p/>
-23- <i>Effects:</i> Applies <ins>the function object</ins> <code>f</code> to the result of dereferencing every iterator in the range 
<code>[first, first + n).</code> [&hellip;]
<p/>
[&hellip;]
</p>
</blockquote>
</blockquote>
</li>
</ol>




</body>
</html>
