<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 225: std:: algorithms use of other unqualified algorithms</title>
<meta property="og:title" content="Issue 225: std:: algorithms use of other unqualified algorithms">
<meta property="og:description" content="C++ library issue. Status: CD1">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue225.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="225"><a href="lwg-defects.html#225">225</a>. std:: algorithms use of other unqualified algorithms</h3>
<p><b>Section:</b> 16.4.6.4 <a href="https://wg21.link/global.functions">[global.functions]</a> <b>Status:</b> <a href="lwg-active.html#CD1">CD1</a>
 <b>Submitter:</b> Dave Abrahams <b>Opened:</b> 2000-04-01 <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#global.functions">issues</a> in [global.functions].</p>
<p><b>View all issues with</b> <a href="lwg-status.html#CD1">CD1</a> status.</p>
<p><b>Discussion:</b></p>
<p>Are algorithms in std:: allowed to use other algorithms without qualification, so functions in
user namespaces might be found through Koenig lookup?</p>
<p>For example, a popular standard library implementation includes this
implementation of std::unique:</p>
<blockquote>
<pre>namespace std {
    template &lt;class _ForwardIter&gt;
    _ForwardIter unique(_ForwardIter __first, _ForwardIter __last) {
      __first = adjacent_find(__first, __last);
      return unique_copy(__first, __last, __first);
    }
    }</pre>
</blockquote>
<p>Imagine two users on opposite sides of town, each using unique on his own
sequences bounded by my_iterators . User1 looks at his standard library
implementation and says, &quot;I know how to implement a more efficient
unique_copy for my_iterators&quot;, and writes:</p>
<blockquote>
<pre>namespace user1 {
    class my_iterator;
    // faster version for my_iterator
    my_iterator unique_copy(my_iterator, my_iterator, my_iterator);
    }</pre>
</blockquote>
<p>user1::unique_copy() is selected by Koenig lookup, as he intended.</p>
<p>User2 has other needs, and writes:</p>
<blockquote>
<pre>namespace user2 {
    class my_iterator;
    // Returns true iff *c is a unique copy of *a and *b.
    bool unique_copy(my_iterator a, my_iterator b, my_iterator c);
    }</pre>
</blockquote>
<p>User2 is shocked to find later that his fully-qualified use of
std::unique(user2::my_iterator, user2::my_iterator, user2::my_iterator) fails to
compile (if he's lucky). Looking in the standard, he sees the following Effects
clause for unique():</p>
<blockquote>
  <p>Effects: Eliminates all but the first element from every consecutive group
  of equal elements referred to by the iterator i in the range [first, last) for
  which the following corresponding conditions hold: *i == *(i - 1) or pred(*i,
  *(i - 1)) != false</p>
</blockquote>
<p>The standard gives user2 absolutely no reason to think he can interfere with
std::unique by defining names in namespace user2. His standard library has been
built with the template export feature, so he is unable to inspect the
implementation. User1 eventually compiles his code with another compiler, and
his version of unique_copy silently stops being called. Eventually, he realizes
that he was depending on an implementation detail of his library and had no
right to expect his unique_copy() to be called portably.</p>
<p>On the face of it, and given above scenario, it may seem obvious that the
implementation of unique() shown is non-conforming because it uses unique_copy()
rather than ::std::unique_copy(). Most standard library implementations,
however, seem to disagree with this notion.</p>
<p> <i>[Tokyo:&nbsp; Steve Adamczyk from
the core working group indicates that &quot;std::&quot; is sufficient;&nbsp;
leading &quot;::&quot; qualification is not required because any namespace
qualification is sufficient to suppress Koenig lookup.]</i></p>


<p id="res-225"><b>Proposed resolution:</b></p>
<p>Add a paragraph and a note at the end of 
16.4.6.4 <a href="https://wg21.link/global.functions">[global.functions]</a>:</p>
<blockquote>

<p>Unless otherwise specified, no global or non-member function in the
standard library shall use a function from another namespace which is
found through <i>argument-dependent name lookup</i> (6.5.4 <a href="https://wg21.link/basic.lookup.argdep">[basic.lookup.argdep]</a>).</p>

<p>[Note: the phrase "unless otherwise specified" is intended to
allow Koenig lookup in cases like that of ostream_iterators:<br/>

<br/>
  Effects:</p>
  <blockquote>
<p>*out_stream &lt;&lt; value;<br/>
      if(delim != 0) *out_stream &lt;&lt; delim;<br/>
      return (*this);</p>
    <p>--end note]</p>
  </blockquote>
</blockquote>

<p><i>[Tokyo: The LWG agrees that this is a defect in the standard, but
is as yet unsure if the proposed resolution is the best
solution. Furthermore, the LWG believes that the same problem of
unqualified library names applies to wording in the standard itself,
and has opened issue <a href="lwg-defects.html#229" title="Unqualified references of other library entities (Status: CD1)">229</a><sup><a href="https://cplusplus.github.io/LWG/issue229" title="Latest snapshot">(i)</a></sup> accordingly. Any resolution of
issue <a href="lwg-defects.html#225" title="std:: algorithms use of other unqualified algorithms (Status: CD1)">225</a><sup><a href="https://cplusplus.github.io/LWG/issue225" title="Latest snapshot">(i)</a></sup> should be coordinated with the resolution of
issue <a href="lwg-defects.html#229" title="Unqualified references of other library entities (Status: CD1)">229</a><sup><a href="https://cplusplus.github.io/LWG/issue229" title="Latest snapshot">(i)</a></sup>.]</i></p>


<p><i>[Toronto: The LWG is not sure if this is a defect in the
standard.  Most LWG members believe that an implementation of
<code>std::unique</code> like the one quoted in this issue is already
illegal, since, under certain circumstances, its semantics are not
those specified in the standard.  The standard's description of
<code>unique</code> does not say that overloading <code>adjacent_find</code>
should have any effect.]</i></p>


<p><i>[Cura&ccedil;ao: An LWG-subgroup spent an afternoon working on issues
225, 226, and 229.  Their conclusion was that the issues should be
separated into an LWG portion (Howard's paper, N1387=02-0045), and a
EWG portion (Dave will write a proposal). The LWG and EWG had
(separate) discussions of this plan the next day.  The proposed
resolution for this issue is in accordance with Howard's paper.]</i></p>




<p><b>Rationale:</b></p>
<p>It could be argued that this proposed isn't strictly necessary,
  that the Standard doesn't grant implementors license to write a
  standard function that behaves differently than specified in the
  Standard just because of an unrelated user-defined name in some
  other namespace.  However, this is at worst a clarification.  It is
  surely right that algorithsm shouldn't pick up random names, that
  user-defined names should have no effect unless otherwise specified.
  Issue <a href="lwg-defects.html#226" title="User supplied specializations or overloads of namespace std function templates (Status: CD1)">226</a><sup><a href="https://cplusplus.github.io/LWG/issue226" title="Latest snapshot">(i)</a></sup> deals with the question of when it is
  appropriate for the standard to explicitly specify otherwise.</p>





</body>
</html>
