This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of C++23 status.

3171. LWG 2989 breaks directory_entry stream insertion

Section: 31.12.10 [fs.class.directory.entry] Status: C++23 Submitter: Tim Song Opened: 2018-12-03 Last modified: 2023-11-22

Priority: 2

View all other issues in [fs.class.directory.entry].

View all issues with C++23 status.

Discussion:

directory_entry has a conversion function to const path& and depends on path's stream insertion operator for stream insertion support, which is now broken after LWG 2989(i) made it a hidden friend.

This does not appear to be intended.

[2018-12-21 Reflector prioritization]

Set Priority to 2

[2019-02; Kona Wednesday night issue processing]

Status to Open; Marshall to move definition inline and re-vote on reflector.

Jonathan to write a paper about how to specify "hidden friends".

Previous resolution [SUPERSEDED]:

This wording is relative to N4778.

  1. Modify [fs.class.directory_entry], class directory_entry synopsis, as follows:

    namespace std::filesystem {
      class directory_entry {
      public:
        […]
      private:
        filesystem::path pathobject;     // exposition only
        friend class directory_iterator; // exposition only
    
        template<class charT, class traits>
          friend basic_ostream<charT, traits>&
            operator<<(basic_ostream<charT, traits>& os, const directory_entry& d);
      };
    }
    
  2. Add a new subclause at the end of [fs.class.directory_entry], as follows:

    28.11.11.4 Inserter [fs.dir.entry.io]

    template<class charT, class traits>
      friend basic_ostream<charT, traits>&
        operator<<(basic_ostream<charT, traits>& os, const directory_entry& d);
    

    -1- Effects: Equivalent to: return os << d.path();

[2020-05-02; Daniel resyncs wording with recent working draft and comments]

We have now the paper P1965R0, which introduced a specification of what friend functions in the library specification (see 16.4.6.6 [hidden.friends]) are supposed to mean, there is no longer an inline definition needed to clarify the meaning. In addition to updating the change of section names the provided wording has moved the friend declaration into the public part of the class definition as have done in all other cases where we take advantage of "hidden friends" declarations.

[2020-08-21 Issue processing telecon: moved to Tentatively Ready]

[2020-11-09 Approved In November virtual meeting. Status changed: Tentatively Ready → WP.]

Proposed resolution:

This wording is relative to N4861.

  1. Modify 31.12.10 [fs.class.directory.entry], class directory_entry synopsis, as follows:

    namespace std::filesystem {
      class directory_entry {
      public:
        […]
        bool operator==(const directory_entry& rhs) const noexcept;
        strong_ordering operator<=>(const directory_entry& rhs) const noexcept;
        
        // 29.11.11.? [fs.dir.entry.io], inserter    
        template<class charT, class traits>
          friend basic_ostream<charT, traits>&
            operator<<(basic_ostream<charT, traits>& os, const directory_entry& d);
      private:
        […]
      };
    }
    
  2. Add a new subclause at the end of 31.12.10 [fs.class.directory.entry], as indicated:

    29.11.11.? Inserter [fs.dir.entry.io]

    template<class charT, class traits>
      friend basic_ostream<charT, traits>&
        operator<<(basic_ostream<charT, traits>& os, const directory_entry& d);
    

    -?- Effects: Equivalent to: return os << d.path();