为什么无法从`std :: filesystem :: path`迭代器构造`std :: filesystem :: path`?

时间:2018-12-12 12:45:29

标签: c++ c++17 std-filesystem

以下代码旨在在存在路径的情况下剥离路径的第一部分:

#include <filesystem>

std::filesystem::path strip_prefix(std::filesystem::path p)
{      
  if (auto it{p.begin()}; it != p.end())
  {
    ++it;
    return std::filesystem::path(it, p.end());
  }

  return p;
}

(请参阅:https://godbolt.org/z/wkXhcw

我很惊讶地发现这行不通。由于路径构造函数仅采用对字符序列进行迭代的迭代器,因此代码无法编译。我可以看到它的用法,但是为什么将构造限制为仅此类迭代器?我认为不支持从其自己的迭代器构造路径是违反直觉的。据我所知,大多数其他STL类型都支持这种用法。

除了完全重建一条新路径之外,什么是实现相同目标的有效实施方式?

更新:在这种情况下,我发现以下讨论是相关的/有趣的:http://boost.2283326.n4.nabble.com/boost-filesystem-path-frustration-td4641734.html。我同意戴夫的看法。我认为将路径视为路径元素的容器是一种很自然的方式(从程序员的角度来看)。

1 个答案:

答案 0 :(得分:5)

将段串联以创建新的path的最简单解决方案就是std::accumulate()

对于您的特定用例,我会这样做:

std::filesystem::path strip_prefix(std::filesystem::path p)
{
    if(p.empty()) return p;
    return std::accumulate(std::next(p.begin()), p.end(), 
                           std::filesystem::path{}, std::divides{});
}

至于为什么没有构造函数(或者可能是自由函数)来执行此操作?我不知道。在使用路径时,这似乎有点需要,但是如果通过调用标准算法可以达到相同的结果,委员会确实不愿意在标准类中添加便利功能。