path
's other operators should be hidden friends as wellSection: 31.12.6.8 [fs.path.nonmember] Status: C++20 Submitter: Billy O'Neal III Opened: 2018-02-13 Last modified: 2021-02-25
Priority: 2
View all issues with C++20 status.
Discussion:
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.
[2018-02-20, Priority set to 2 after mailing list discussion]
[2018-08-23 Batavia Issues processing]
Status to Tentatively Ready
[2018-11, Adopted in San Diego]
Proposed resolution:
This wording is relative to N4713.
All drafting notes from LWG 2989 apply here too.Modify 31.12.4 [fs.filesystem.syn], header <filesystem>
synopsis, as indicated:
[…] // 31.12.6.8 [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);[…]
Modify 31.12.6.8 [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); […]
Modify 31.12.6 [fs.class.path], class path
synopsis, as indicated:
class path { public: […] // 31.12.6.5.5 [fs.path.modifiers], modifiers […] // 31.12.6.8 [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); // 31.12.6.5.6 [fs.path.native.obs], native format observers […] };