filesystem::operator/ 提升和标准中的不同行为

filesystem::operator/ different behaviour in boost and std

提问人:Dundo 提问时间:9/6/2021 最后编辑:Dundo 更新时间:9/7/2021 访问量:394

问:

我正在尝试从 移植到 .在此过程中,我遇到了一些代码,其中似乎以不同的方式运行。boost::filesystemstd::filesystembooststd

以下代码显示了该行为:

#include <iostream>
#include <filesystem>
#include <boost/filesystem.hpp>

template<typename T>
void TestOperatorSlash()
{
    const std::string foo = "Foo";
    const std::string bar = "Bar";
    const T start = "\\";
    std::string sep;
    sep += T::preferred_separator;
    const auto output = start / (foo + bar) / sep;
    std::cout << output << '\n';
}

int main(int argc, char** argv)
{
    TestOperatorSlash<std::filesystem::path>();
    TestOperatorSlash<boost::filesystem::path>();
}

代码在输出中给出:

"\\"
"\FooBar\"

我的预期行为是 ,我不明白会发生什么。booststd::filesystem

为什么我会得到? 为什么 和 的行为不同?"\\"operator/pathbooststd

编辑:

在理解了行为的动机并给出这个问题的答案之后,我决定将该函数用于第二个参数,即当我有绝对路径时。std::filesystem::operator/path::relative_path()operator/

通过这种方式,我可以模仿 . 因此,例如:boost::filesystem

#include <iostream>
#include <filesystem>
namespace fs = std::filesystem;
int main(int argc, char** argv)
{
    fs::path foo = "\\foo";
    fs::path bar = "\\bar";
    auto foobar0 = foo / bar;                   // Evaluates to \\bar
    auto foobar1  = foo / bar.relative_path();  // Evaluates to \\foo\\bar
}
C++ Boost 文件系统 标准

评论

0赞 Davis Herring 9/5/2023
如果要在 中生成一个 final,你可以使用 ,它产生的结果当然比使用 少一个字符。/path/ ""/ "a"

答:

4赞 user14215102 9/6/2021 #1

Boost 将合并冗余分隔符。

https://www.boost.org/doc/libs/1_68_0/libs/filesystem/doc/reference.html#path-appends

将 path::p referred_separator 附加到路径名,转换格式和 如果需要,则进行编码 ([path.arg.convert]),除非:

an added separator would be redundant, ...

而 std::filesystem 在第二个参数中看到一个前导分隔符,作为替换部分或全部原始路径的指令:/

https://en.cppreference.com/w/cpp/filesystem/path/append

path("C:foo") / "/bar";  // yields "C:/bar"        (removes relative path, then appends)

你是否想要:

const auto output = start / (foo + bar) / "";

相反?

评论

1赞 Dundo 9/6/2021
我不知道 的“替换”机制。我在这里找到了一些关于它的解释。谢谢你的回答。std::filesystem::path::append