<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 2652: [filesys.ts] [PDTS] Better to avoid deriving from std::iterator</title>
<meta property="og:title" content="Issue 2652: [filesys.ts] [PDTS] Better to avoid deriving from std::iterator">
<meta property="og:description" content="C++ library issue. Status: TS">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue2652.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#TS">TS</a> status.</em></p>
<h3 id="2652"><a href="lwg-defects.html#2652">2652</a>. [filesys.ts] [PDTS] Better to avoid deriving from <code>std::iterator</code></h3>
<p><b>Section:</b> 13 [filesys.ts::class.directory_iterator], 14 [filesys.ts::class.rec.dir.itr] <b>Status:</b> <a href="lwg-active.html#TS">TS</a>
 <b>Submitter:</b> Stephan T. Lavavej <b>Opened:</b> 2014-02-03 <b>Last modified:</b> 2017-07-30</p>
<p><b>Priority: </b>Not Prioritized
</p>
<p><b>View all other</b> <a href="lwg-index.html#filesys.ts::class.directory_iterator">issues</a> in [filesys.ts::class.directory_iterator].</p>
<p><b>View all issues with</b> <a href="lwg-status.html#TS">TS</a> status.</p>
<p><b>Discussion:</b></p>
<p><b>Addresses: filesys.ts</b></p>
<p>Although the Standard has made this mistake almost a dozen times, I recommend not
depicting <code>directory_iterator</code> and <code>recursive_directory_iterator</code> as deriving from
<code>std::iterator</code>, since that's a binding requirement on implementations.
Instead they should be depicted as having the appropriate typedefs, and leave it up to
implementers to decide how to provide them. (The difference is observable to users with
<code>is_base_of</code>, not that they should be asking that question.)</p>

<p><i>[2014-02-08 Daniel comments and provides wording]</i></p>

<p>
This issue is basically similar to the kind of solution that had been used to remove the
requirement to derive from <code>unary_function</code> and friends as described by
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3198.htm">N3198</a> and
I'm strongly in favour to follow that spirit here as well. I'd like to add that basically all
"newer" iterator types (such as the <code>regex</code> related iterator don't derive from
<code>std::iterator</code> either.
<p/>
Another reason to change the current specification is the fact that it currently says that
the member types <code>pointer</code> and <code>reference</code> would be determined to <code>value_type*</code>
and <code>value_type&amp;</code> (that is mutable pointers and references), which conflicts with the specification 
of the return types of the following members:
</p>
<blockquote><pre>
const directory_entry&amp; operator*() const;
const directory_entry* operator-&gt;() const;
</pre></blockquote>
<p>
The proposed fording fixes this by correcting these <code>typedef</code> to corresponding <code>const</code> access.
<p/>
The very same objections had been expressed by issue <a href="lwg-closed.html#2651" title="[filesys.ts] [PDTS] directory_iterator, recursive_directory_iterator, pointer/reference typedefs wrong (Status: Dup)">2651</a><sup><a href="https://cplusplus.github.io/LWG/issue2651" title="Latest snapshot">(i)</a></sup> and the below given wording resolves this
issue as well.
</p>

  <p><i>[2014-02-13 LWG/SG-3 Issaquah: Proposed wording accepted.]</i></p>



<p id="res-2652"><b>Proposed resolution:</b></p>
<p>This wording is relative to <a href="http://wiki.edg.com/twiki/pub/Wg21issaquah/SG3/working-draft.html">SG3 working draft</a>.</p>

<ol>
<li><p>Change class <code>directory_iterator</code> synopsis, [class.directory_iterator], as indicated:</p>
<blockquote><pre>
namespace std { namespace tbd { namespace filesystem {

      class directory_iterator <del>:
        public iterator&lt;input_iterator_tag, directory_entry&gt;</del>
      {
      public:
        <ins>typedef directory_entry        value_type;</ins>
        <ins>typedef ptrdiff_t              difference_type;</ins>
        <ins>typedef const directory_entry* pointer;</ins>
        <ins>typedef const directory_entry&amp; reference;</ins>
        <ins>typedef input_iterator_tag     iterator_category;</ins>

        // member functions
        [&hellip;]
      };

} } }  // namespaces std::tbd::filesystem
</pre></blockquote>
</li>

<li><p>Change class <code>recursive_directory_iterator</code> synopsis, [class.rec.dir.itr], as indicated:</p>
<blockquote><pre>
namespace std { namespace tbd { namespace filesystem {

      class recursive_directory_iterator <del>:
        public iterator&lt;input_iterator_tag, directory_entry&gt;</del>
      {
      public:
        <ins>typedef directory_entry        value_type;</ins>
        <ins>typedef ptrdiff_t              difference_type;</ins>
        <ins>typedef const directory_entry* pointer;</ins>
        <ins>typedef const directory_entry&amp; reference;</ins>
        <ins>typedef input_iterator_tag     iterator_category;</ins>

        // constructors and destructor
        [&hellip;]
        
        // modifiers
        recursive_directory_iterator&amp; operator=(const recursive_directory_iterator&amp;) = default;
        recursive_directory_iterator&amp; operator=(recursive_directory_iterator&amp;&amp;) = default;
        
        <ins>const directory_entry&amp; operator*() const;</ins>
        <ins>const directory_entry* operator-&gt;() const;</ins>

        recursive_directory_iterator&amp; operator++();
        recursive_directory_iterator&amp; increment(error_code&amp; ec);

        [&hellip;]
      };

} } }  // namespaces std::tbd::filesystem
</pre></blockquote>
</li>
</ol>





</body>
</html>
