Title
LWG 2989 missed that all path's other operators should be hidden friends as well
Status
c++20
Section
[fs.path.nonmember]
Submitter
Billy O'Neal III

Created on 2018-02-13.00:00:00 last changed 38 months ago

Messages

Date: 2018-11-12.04:39:29

Proposed resolution:

This wording is relative to N4713.

All drafting notes from LWG 2989 apply here too.

  1. Modify [fs.filesystem.syn], header <filesystem> synopsis, as indicated:

    […]
    // [fs.path.nonmember], path non-member functions
    void swap(path& lhs, path& rhs) noexcept;
    size_t hash_value(const path& p) noexcept;
    
    bool operator==(const path& lhs, const path& rhs) noexcept;
    bool operator!=(const path& lhs, const path& rhs) noexcept;
    bool operator< (const path& lhs, const path& rhs) noexcept;
    bool operator<=(const path& lhs, const path& rhs) noexcept;
    bool operator> (const path& lhs, const path& rhs) noexcept;
    bool operator>=(const path& lhs, const path& rhs) noexcept;
    
    path operator/ (const path& lhs, const path& rhs);
    […]
    
  2. Modify [fs.path.nonmember] as indicated:

    […]
    friend bool operator< (const path& lhs, const path& rhs) noexcept;
    […]
    friend bool operator<=(const path& lhs, const path& rhs) noexcept;
    […]
    friend bool operator> (const path& lhs, const path& rhs) noexcept;
    […]
    friend bool operator>=(const path& lhs, const path& rhs) noexcept;
    […]
    friend bool operator==(const path& lhs, const path& rhs) noexcept;
    […]
    friend bool operator!=(const path& lhs, const path& rhs) noexcept;
    […]
    friend path operator/ (const path& lhs, const path& rhs);
    […]
    
  3. Modify [fs.class.path], class path synopsis, as indicated:

    class path {
    public:
      […]
      // [fs.path.modifiers], modifiers
      […]
      
      // [fs.path.nonmember], non-member operators
      friend bool operator< (const path& lhs, const path& rhs) noexcept;
      friend bool operator<=(const path& lhs, const path& rhs) noexcept;
      friend bool operator> (const path& lhs, const path& rhs) noexcept;
      friend bool operator>=(const path& lhs, const path& rhs) noexcept;
      friend bool operator==(const path& lhs, const path& rhs) noexcept;
      friend bool operator!=(const path& lhs, const path& rhs) noexcept;
      
      friend path operator/ (const path& lhs, const path& rhs);
      
      // [fs.path.native.obs], native format observers
      […]
    };
    
Date: 2018-11-12.04:39:29

[ 2018-11, Adopted in San Diego ]

Date: 2018-08-23.00:00:00

[ 2018-08-23 Batavia Issues processing ]

Status to Tentatively Ready

Date: 2018-02-15.00:00:00

[ 2018-02-20, Priority set to 2 after mailing list discussion ]

Date: 2018-02-13.00:00:00

Consider the following program:

// See godbolt link
#include <assert.h>
#include <string>
#include <filesystem>

using namespace std;
using namespace std::filesystem;

int main() {
  bool b = L"a//b" == std::string("a/b");
  assert(b); // passes. What?!
  return b;
}

L"a" gets converted into a path, and the string gets converted into a path, and then those paths are compared for equality. But path equality comparison doesn't work anything like string equality comparison, leading to surprises.

path's other operators should be made hidden friends as well, so that one side or the other of a given operator is of type path before those conversions apply.

History
Date User Action Args
2021-02-25 10:48:01adminsetstatus: wp -> c++20
2018-11-12 04:39:29adminsetmessages: + msg10192
2018-11-12 04:39:29adminsetstatus: voting -> wp
2018-10-08 05:13:59adminsetstatus: ready -> voting
2018-08-24 13:31:33adminsetmessages: + msg10127
2018-08-24 13:31:33adminsetstatus: new -> ready
2018-03-04 15:38:38adminsetmessages: + msg9713
2018-02-15 19:20:54adminsetmessages: + msg9686
2018-02-13 00:00:00admincreate