2652. [filesys.ts] [PDTS] Better to avoid deriving from std::iterator

Section: 99 [filesys.ts::class.directory_iterator], 99 [filesys.ts::class.rec.dir.itr] Status: TS Submitter: Stephan T. Lavavej Opened: 2014-02-03 Last modified: 2017-07-30

Priority: Not Prioritized

View all other issues in [filesys.ts::class.directory_iterator].

View all issues with TS status.

Discussion:

Addresses: filesys.ts

Although the Standard has made this mistake almost a dozen times, I recommend not depicting directory_iterator and recursive_directory_iterator as deriving from std::iterator, 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 is_base_of, not that they should be asking that question.)

[2014-02-08 Daniel comments and provides wording]

This issue is basically similar to the kind of solution that had been used to remove the requirement to derive from unary_function and friends as described by N3198 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 regex related iterator don't derive from std::iterator either.

Another reason to change the current specification is the fact that it currently says that the member types pointer and reference would be determined to value_type* and value_type& (that is mutable pointers and references), which conflicts with the specification of the return types of the following members:

const directory_entry& operator*() const;
const directory_entry* operator->() const;

The proposed fording fixes this by correcting these typedef to corresponding const access.

The very same objections had been expressed by issue 2651 and the below given wording resolves this issue as well.

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

Proposed resolution:

This wording is relative to SG3 working draft.

  1. Change class directory_iterator synopsis, [class.directory_iterator], as indicated:

    namespace std { namespace tbd { namespace filesystem {
    
          class directory_iterator :
            public iterator<input_iterator_tag, directory_entry>
          {
          public:
            typedef directory_entry        value_type;
            typedef ptrdiff_t              difference_type;
            typedef const directory_entry* pointer;
            typedef const directory_entry& reference;
            typedef input_iterator_tag     iterator_category;
    
            // member functions
            […]
          };
    
    } } }  // namespaces std::tbd::filesystem
    
  2. Change class recursive_directory_iterator synopsis, [class.rec.dir.itr], as indicated:

    namespace std { namespace tbd { namespace filesystem {
    
          class recursive_directory_iterator :
            public iterator<input_iterator_tag, directory_entry>
          {
          public:
            typedef directory_entry        value_type;
            typedef ptrdiff_t              difference_type;
            typedef const directory_entry* pointer;
            typedef const directory_entry& reference;
            typedef input_iterator_tag     iterator_category;
    
            // constructors and destructor
            […]
            
            // modifiers
            recursive_directory_iterator& operator=(const recursive_directory_iterator&) = default;
            recursive_directory_iterator& operator=(recursive_directory_iterator&&) = default;
            
            const directory_entry& operator*() const;
            const directory_entry* operator->() const;
    
            recursive_directory_iterator& operator++();
            recursive_directory_iterator& increment(error_code& ec);
    
            […]
          };
    
    } } }  // namespaces std::tbd::filesystem