【问题标题】:c++ fs::path's operator/ counterintuitively overwrites entire path. A solution?c++ fs::path 的 operator/ 违反直觉地覆盖了整个路径。一个办法?
【发布时间】:2020-04-08 08:11:32
【问题描述】:
fs::path p1 = "/q/b";
fs::path p2 = "/";
std::cout << p1 / p2 << std::endl;

will output/.

从这么多角度来看,这是完全出乎意料的:

  • 完全合乎逻辑appending(这就是操作的调用方式,对吗?)something to something 无法覆盖前者。
  • 当前 Unix 路径行为:对于 Linux,“/a/b”与“/a/b/”、“/a/b//”、...相同,因此任何使用它会期望 附加 行为,而不是 覆盖
  • 安全:危险的事情(删除fs::path 的现有值)应该比安全/非破坏性的事情(只是增加fs::path 的现有值)更难做。换句话说,当前行为仅依赖于某人手动检查正在发生的事情。如果您忘记写支票(路径是否从/ 开始)- 您就很不走运了。
  • 最后:我不认为一个只想覆盖路径的人会使用/ 而不是=

我的主要问题,但是,假设的解决方案是什么?请想象一下 p2 路径作为函数的参数出现在您面前,它可能是 /c/dc

我看到的一些(可怕的)选项:

  1. 我可以删除 libcxx 源中的第一个 if:
  path& operator/=(const path& __p) {
    if (__p.is_absolute()) {
      __pn_ = __p.__pn_;
      return *this;
    }
  1. 继续使用operator/ - 但如果我想要更符合 Linux 行为,我需要进行一些检查吗?

  2. 使用concat, operator+= - 但在fs::path("a") + "b" 的情况下不会添加分隔符/

理想情况下,我想覆盖operator/...

有什么建议吗?

【问题讨论】:

    标签: c++


    【解决方案1】:

    这并不违反直觉,因为您没有连接字符串,而是将一条路径附加到另一条路径。 fs::path{"/"} 不代表字符 / 也不代表文件夹分隔符。它代表根路径path::append(和operator/(path))的行为 就是如果第二个操作数是绝对路径,那么结果就是第二个操作数(这里可以假设应该抛出异常)。

    如果要附加目录分隔符,可以这样做:

    fs::path p1 = "/q/b";
    fs::path p2 = "./"; // <-- relative path
    
    std::cout << (p1 / p2).lexically_normal() << std::endl;
    
    // or this
    std::cout << p1.concat("/").lexically_normal() << std::endl;
    

    path::lexically_normal 用于规范化结果,以便在一般情况下您不会得到像 /q/b/.//q/b// 这样的奇怪路径。

    【讨论】:

    • 当然,根据我的经验,我可以看到他们的推理(谁在设计课程),但是,默认选择错误。我认为是这样,因为标准应该对应/描述并很好地适应世界。世界(这里我指的是 Linux)表现不同。在 Linux 中,它字符串的串联。
    • 另外,我澄清了一点我的问题。问题是 p1 和 p2 是函数的参数。我不能在前面加上“。”总是到 p2。如果 p2 是“a”怎么办?如果 p2 是绝对的,我可以从 p2 中删除前导 / ,但这意味着复杂性将加倍......而且这也意味着我不能使用非常方便的 operator/ ... :(
    【解决方案2】:

    由于我在问题中描述的安全问题(在如此无辜的操作中具有破坏性/覆盖行为是很危险的 - path1 / path2),我决定最好的选择是只分叉当前的@987654323 @作为新类型,并更正operator/的代码。

    Here you can find one-header implementation,几乎全部取自clang的libcxx

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-03-29
      • 2011-09-22
      • 1970-01-01
      • 1970-01-01
      • 2022-01-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多