Неожиданный псевдоним с std :: экспериментальный :: directory_iterator

Я использовал экспериментальный std::filesystem реализация в gcc 6.3.1, и столкнулся с некоторым очень неожиданным поведением в отношении std::experimental::filesystem::directory_iterator а также std::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,

Спасибо!

1

Решение

directory_iterators определены как InputIterators и, следовательно, может быть использован только один раз. Оператора сложения const нет, поэтому вам нужно использовать оператор приращения, который модифицирует итератор.

4

Другие решения

Других решений пока нет …