2609. [filesys.ts] [PDTS] Unclear why range-based-for functions return different types

Section: 99 [filesys.ts::fs.filesystem.synopsis] Status: TS Submitter: FI-2 Opened: 2014-01-20 Last modified: 2017-07-30

Priority: Not Prioritized

View all other issues in [filesys.ts::fs.filesystem.synopsis].

View all issues with TS status.

Discussion:

Addresses: filesys.ts

It is unclear why the range-for support functions (begin()/end()) for directory_iterator and recursive_directory_iterator return different types for begin() and end(), namely that begin() returns a reference to const and end() returns a value.

[2014-02-07: Beman Dawes provides comments from the Boost implementation:]

  //  begin() and end() are only used by a range-based for statement in the context of
  //  auto - thus the top-level const is stripped - so returning const is harmless and
  //  emphasizes begin() is just a pass through.

[2014-02-08: Daniel responds to Beman]

The difference in return types becomes relevant, when testing whether e.g. directory_iterator would satisfy the Traversable requirements as currently specified in N3763. Expressed in code form these requirements impose that the following assertion holds:

  static_assert(std::is_same<
      decltype(std::range_begin(std::declval<directory_iterator>())),
      decltype(std::range_end(std::declval<directory_iterator>()))
    >::value, "No Traversable type");
  

Both directory_iterator and recursive_directory_iterator won't satisfy this requirement currently.

[ 2014-02-11 Issaquah: Change begin() argument and return to pass-by-value. See wiki notes for rationale. Beman to provide wording for review next meeting. ]

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

Proposed resolution:

  1. Change 6 [fs.filesystem.synopsis]:

      class directory_iterator;
    
      // enable directory_iterator range-based for statements
      const directory_iterator& begin(const directory_iterator& iter) noexcept;
      directory_iterator end(const directory_iterator&) noexcept;
    
      class recursive_directory_iterator;
    
      // enable recursive_directory_iterator range-based for statements
      const recursive_directory_iterator& begin(const recursive_directory_iterator& iter) noexcept;
      recursive_directory_iterator end(const recursive_directory_iterator&) noexcept;
      
  2. Change 13.2 [directory_iterator.nonmembers]:

    These functions enable use of directory_iterator with C++11 range-based for statements.

    const directory_iterator& begin(constdirectory_iterator& iter) noexcept;

    Returns: iter.

    directory_iterator end(const directory_iterator&) noexcept;

    Returns: directory_iterator().

  3. Change 14.2 [rec.dir.itr.nonmembers]:

    These functions enable use of recursive_directory_iterator with C++11 range-based for statements.

    const recursive_directory_iterator& begin(constrecursive_directory_iterator& iter) noexcept;

    Returns: iter.

    recursive_directory_iterator end(const recursive_directory_iterator&) noexcept;

    Returns: recursive_directory_iterator().