filesystem::operator/ boost 和 std 的不同行为

filesystem::operator/ different behaviour in boost and std

我正在尝试从 boost::filesystem 移植到 std::filesystem。在此过程中,我遇到了一些代码,其中 booststd 的行为似乎不同。

以下代码显示了行为:

#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\"

我的预期行为是 boost 之一,我不明白 std::filesystem 会发生什么。

为什么我得到 "\"? 为什么 pathoperator/ 的行为在 booststd 中不同?

编辑:

在了解了std::filesystem::operator/行为的动机并给出了问题的答案后,我决定对[=21=的第二个参数使用函数path::relative_path() ] 当我有绝对路径时。

这样我就可以模仿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
}

Boost 将合并冗余分隔符。

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

Appends path::preferred_separator to pathname, converting format and encoding if required ([path.arg.convert]), unless:

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) / "";

代替?