std::experimental::directory_iterator 的意外别名

Unexpected aliasing with std::experimental::directory_iterator

我在 gcc 6.3.1 中使用了实验性的 std::filesystem 实现,并且 运行 出现了一些关于 std::experimental::filesystem::directory_iteratorstd::distance 的非常意外的行为。具体来说,在调用 std::distance 之后,原始迭代器似乎已被修改。

在我的代码中尝试查找逻辑错误的一系列无果调试之后,我开始在 directory_iterator 的实现中进行挖掘,最后发现迭代器在内部使用 std::shared_ptr,有一个默认的复制构造函数,我假设 operator++ 必须直接递增托管指针。

以下代码重现了该问题:

#include <iostream>
#include <experimental/filesystem>
namespace fs = std::experimental::filesystem;

int main() {
  auto it = fs::directory_iterator("/etc");
  std::cout << *it << std::endl;
  std::distance(it, fs::directory_iterator{});
  std::cout << *it << std::endl;
}

由于这种实现在传递给期望具有传统值语义的迭代器的函数时会产生非常反直觉的结果(据我所知,所有的 STL 算法),我很难相信这一点是预期的行为,但我犹豫要不要称之为错误。

显然,这个 API 在发布时是实验性的,但我认为它旨在成为文件系统 TS 的忠实实现。我无法访问具有完整 C++17 支持的编译器,因此我一直希望在此期间使用它。

这是预期的行为吗?我是否应该期望 directory_iterator 在未来的版本中以这种方式工作?目前我想我可以使用 boost::filesystem.

谢谢!

directory_iterators are defined to be InputIterators 因此只能使用一次。没有 const 加法运算符,因此您必须使用修改迭代器的增量运算符。