std::filesystem::path::lexically_normal, std::filesystem::path::lexically_relative, std::filesystem::path::lexically_proximate
来自cppreference.com
                    
                                        
                    < cpp | filesystem | path
                    
                                                            
                    |   path lexically_normal() const;  | 
(1) | (C++17 起) | 
|   path lexically_relative(const path& base) const;  | 
(2) | (C++17 起) | 
|   path lexically_proximate(const path& base) const;  | 
(3) | (C++17 起) | 
2) 返回设为相对 
base 的 *this 。 
-  首先,若 root_name() != base.root_name() 为 true 或 is_absolute() != base.is_absolute() 为 true 或 (!has_root_directory() && base.has_root_directory()) 为 true 或 relative_path() 或 base.relative_path() 中的任何文件名能转译为 根名, ,则返回默认构造的 
path。 -  否则,首先确定 
*this和base的首个不匹配元素,如同以 auto [a, b] = mismatch(begin(), end(), base.begin(), base.end()) ,然后 
- 若 a == end() 且 b == base.end() ,则返回 path(".") ;
 -  否则,定义 N 为 [b, base.end()) 中既非 dot 亦非 dot-dot 的非空文件名元素数减去 dot-dot 文件名元素数。若 N < 0 则返回默认构造的 
path。 - 否则,若 N = 0 且 a == end() || a->empty() ,则返回 path(".") 。
 - 否则返回由以下方式合成的对象
 
- 默认构造 path() 后
 - 应用 N 次 operator/=(path("..")) ,之后
 -  对半开范围 
[a, end())中的每个元素应用一次 operator/= 
-  首先,若 root_name() != base.root_name() 为 true 或 is_absolute() != base.is_absolute() 为 true 或 (!has_root_directory() && base.has_root_directory()) 为 true 或 relative_path() 或 base.relative_path() 中的任何文件名能转译为 根名, ,则返回默认构造的 
 
3) 若 lexically_relative(base) 的值不是空路径,则返回它。否则返回 
*this 。参数
(无)
返回值
1) 路径的正常形式
2) 路径的相对形式
3) 路径的接近形式
异常
(无)
注解
这些转换是纯文字的。它们不检查路径是否存在,不跟随符号链接,且完全不访问文件系统。关于 lexically_relative 与 lexically_proximate 跟随符号链接的对应版本,见 relative 与 proximate 。
Windows 上返回路径拥有反斜杠(偏好分隔符)。
POSIX 上相对路径中的文件名均不可接受为 根名 。
示例
运行此代码
#include <iostream> #include <filesystem> #include <cassert> namespace fs = std::filesystem; int main() { assert(fs::path("foo/./bar/..").lexically_normal() == "foo/"); assert(fs::path("foo/.///bar/../").lexically_normal() == "foo/"); 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"); }
 
缺陷报告
下列更改行为的缺陷报告追溯地应用于以前出版的 C++ 标准。
| DR | 应用于 | 出版时的行为 | 正确行为 | 
|---|---|---|---|
| LWG 3070 | C++17 | 亦能为根名的文件名可能导致诧异的结果 | 当作错误情况 | 
| LWG 3096 | C++17 | 错误地处理了尾随 "/" 和 "/." | 已更正 | 
参阅
|    (C++17)  | 
  组成一个相对路径  (函数)  |