如何使用 C++17 的文件系统检查路径是否引用 Windows 中的卷?

How to check if a path refers to a volume in Windows with C++17's filesystem?

我在 Windows 上使用 C++17。据我所知,std::filesystem 没有 is_root() 函数或类似的东西告诉我路径是否直接指向 C: 或 D: 或任何其他卷。我错过了什么吗?

目前我正在这样做:

if (path.parent_path() == path)
{
    //
}

看起来它可以正常工作,但我不知道这是否遗漏了任何边缘情况。有没有更好的方法?

编辑:

我想检查整个路径是否只是卷名(可能后跟一个可选的斜杠或反斜杠)。

所以,如果有这样的函数,我希望它的行为如下:

namespace fs = std::filesystem;
is_root(fs::path{ "C:" }); // true
is_root(fs::path{ "D:\"}); // true
is_root(fs::path{ "C:/users" }) // false
is_root(fs::current_path()) // usually false, unless the executable was started directly in C: or D: or any other drive

首先,检查是否has_root_name();没有一个,显然没有指定卷

困难的部分是弄清楚它是否只有有根名称。这很复杂,因为如果路径指定了根目录,您还想忽略它。

迭代器范围是一个很好的、性能友好的解决方案。如果它有一个根名,那么 begin() 指向那个根名。因此,如果您增加它,它会指向路径中的下一个组件。

如果路径同时包含根名和根目录,则根名后的部分为根目录。因此,如果您递增超过 that,迭代器要么指向另一个组件,要么已经到达范围的 end。如果它在 end,那么什么都没有,你知道路径是 "just a volume"。

代码如下所示:

bool is_volume(const fs::path &p)
{
  if(!p.has_root_name()) return false;

  auto it = p.begin();
  ++it; //Skip the root-name

  if(p.has_root_directory())
    ++it; //Skip the root-directory.

  if(it == p.end())
    return true;

  return false;
}