path lexically_normal() const; | (1) | (since C++17) |
path lexically_relative(const path& base) const; | (2) | (since C++17) |
path lexically_proximate(const path& base) const; | (3) | (since C++17) |
*this
made relative to base
. root_name() != base.root_name()
is true
or is_absolute() != base.is_absolute()
is true
or (!has_root_directory() && base.has_root_directory())
is true
or any filename in relative_path()
or base.relative_path()
can be interpreted as a root-name, returns a default-constructed path. *this
and base
as if by auto [a, b] = mismatch(begin(), end(), base.begin(), base.end())
, then a == end()
and b == base.end()
, returns path(".")
; [b, base.end())
, minus the number of dot-dot filename elements, If N < 0, returns a default-constructed path. a == end() || a->empty()
, returns path(".")
. path()
followed by operator/=(path(".."))
, followed by operator/=
for each element in the half-open range [a, end())
lexically_relative(base)
is not an empty path, return it. Otherwise return *this
.(none).
May throw implementation-defined exceptions.
These conversions are purely lexical. They do not check that the paths exist, do not follow symlinks, and do not access the filesystem at all. For symlink-following counterparts of lexically_relative
and lexically_proximate
, see relative
and proximate
.
On Windows, the returned path
has backslashes (the preferred separators).
On POSIX, no filename in a relative path is acceptable as a root-name.
#include <iostream> #include <filesystem> #include <cassert> namespace fs = std::filesystem; int main() { assert(fs::path("a/./b/..").lexically_normal() == "a/"); assert(fs::path("a/.///b/../").lexically_normal() == "a/"); assert(fs::path("/a/d").lexically_relative("/a/b/c") == "../../d"); assert(fs::path("/a/b/c").lexically_relative("/a/d") == "../b/c"); assert(fs::path("a/b/c").lexically_relative("a") == "b/c"); assert(fs::path("a/b/c").lexically_relative("a/b/c/x/y") == "../.."); assert(fs::path("a/b/c").lexically_relative("a/b/c") == "."); assert(fs::path("a/b").lexically_relative("c/d") == "../../a/b"); assert(fs::path("a/b").lexically_relative("/a/b") == ""); assert(fs::path("a/b").lexically_proximate("/a/b") == "a/b"); }
The following behavior-changing defect reports were applied retroactively to previously published C++ standards.
DR | Applied to | Behavior as published | Correct behavior |
---|---|---|---|
LWG 3070 | C++17 | a filename that can also be a root-name may cause surprising result | treated as error case |
LWG 3096 | C++17 | trailing "/" and "/." are handled incorrectly | corrected |
(C++17) | composes a relative path (function) |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/cpp/filesystem/path/lexically_normal