Я использовал экспериментальный 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
,
Спасибо!
directory_iterators определены как InputIterators и, следовательно, может быть использован только один раз. Оператора сложения const нет, поэтому вам нужно использовать оператор приращения, который модифицирует итератор.
Других решений пока нет …