recursive_directory_iterator, for_each and execution

Stan Huang 421 Reputation points
2021-06-25T09:26:03.567+00:00

I've been using VS2019 and I got an error in compiling my code snippet, as below. There are at least three compilation errors:

  1. E0135: Namespace "std::experimental::filesystem" has no member "recursive_directory_iterator"
  2. E0276: name followed by '::' must be a class or namespace name
  3. E0304 no instance of function template "std::for_each" matches the argument list

How come?

namespace fs = std::experimental::filesystem;
void remove_old_files(const std::regex& re, const std::string& dir,
size_t ndays) {
std::time_t now =
std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());

std::vector<fs::path> delayed_remove;
for (const auto& entry : fs::recursive_directory_iterator(dir)) {
    std::smatch result;
    std::string name = entry.path().filename();
    if (std::regex_match(name, result, re)) {
        assert(result.size() >= 4);
        std::tm tm{};

        tm.tm_year = std::stoi(result[1].str()) - 1900;
        tm.tm_mon = std::stoi(result[2].str()) - 1;
        tm.tm_mday = std::stoi(result[3].str());
        std::time_t file_date = std::mktime(&tm);

        if (file_date < now && now - file_date > ndays * 86400) {
            std::cerr << "sheduled to erase:" << entry.path() << '\n';
            delayed_remove.push_back(entry.path());
        }
    }
}
std::for_each(std::execution::par, delayed_remove.begin(),
    delayed_remove.end(), [](const auto& p) { fs::remove(p); });

}

Developer technologies C++
0 comments No comments
{count} votes

1 answer

Sort by: Most helpful
  1. David Lowndes 4,726 Reputation points
    2021-06-25T09:43:45.637+00:00

    The following compiles OK for me as C++17:

    #include <vector>
    #include <filesystem>
    #include <chrono>
    #include <regex>
    #include <algorithm>
    #include <execution>
    
    namespace fs = std::filesystem;
    
    void remove_old_files(const std::regex& re, const std::string& dir,
        size_t ndays) {
        std::time_t now =
            std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
    
        std::vector<fs::path> delayed_remove;
        for (const auto& entry : fs::recursive_directory_iterator(dir)) {
            std::smatch result;
            std::string name = entry.path().filename().string();
            if (std::regex_match(name, result, re)) {
                std::tm tm{};
                tm.tm_year = std::stoi(result[1].str()) - 1900;
                tm.tm_mon = std::stoi(result[2].str()) - 1;
                tm.tm_mday = std::stoi(result[3].str());
                std::time_t file_date = std::mktime(&tm);
                if (file_date < now && now - file_date > ndays * 86400) {
                    std::cerr << "sheduled to erase:" << entry.path() << '\n';
                    delayed_remove.push_back(entry.path());
                }
            }
        }
        std::for_each(std::execution::par, delayed_remove.begin(),
            delayed_remove.end(), [](const auto& p) { fs::remove(p); });
    }
    

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.