给出以下代码:
#include <iostream>
#include <filesystem>
namespace fs = std::filesystem;
int main()
{
fs::path fsBase = "/base";
fs::path fsAppend = "/append";
auto fsResult = fsBase / fsAppend;
std::cout << "fsResult: " << fsResult << std::endl;
return 0;
}
通常,预期的结果是/base/append
,但实际上它给了/append
。
fs::path::append的描述确实表明了这种行为:
如果p.is_absolute()|| (p.has_root_name()&& p.root_name()!= root_name()),然后用p替换当前路径,如同操作符=(p)并完成。
然而,std::experimental::filesystem
和boost::filesystem
的行为是不同的,这给出了预期的/base/append
。见examples。
问题是为什么它的行为如此?为什么用append()
函数替换路径?
fsAppend
是一个绝对的路径,因为它从/
开始,你在一个系统,如POSIX,其中以/
开头的路径是绝对的。
将一条绝对路径附加到另一条绝对路径没有任何意义(对我来说抛出异常实际上是最自然的结果)。什么应该C:\foo.txt
附加C:\bar.txt
的结果?
在experimental::fs
中,规则是如果第二个参数的.native()
以目录分隔符开始,那么它被视为追加目的的相对路径,即使它可能是其他上下文中的绝对路径!
标准化文件系统清楚地将绝对路径与相对路径区分开来,试图避免POSIX系统上出现的这种模糊性。
可以在P0492R2 US77找到更改的记录。
请注意,您可以使用+=
而不是/
进行连接(应该按预期执行),或者在使用/
之前使第二个参数相对。
另请参阅this answer以进一步比较experimental
和最终确定。