'std::filesystem' has not been declared after including <experimental/filesystem>

21,008

Solution 1

You use std::filesystem::directory_iterator. std::filesystem::directory_iterator and the entire namespace std::filesystem are declared in the header <filesystem>.

You haven't included the header <filesystem>. Instead, you've included <experimental/filesystem>. This header does not declare std::filesystem::directory_iterator. Instead, it declares std::experimental::filesystem::directory_iterator.

You can consistently use either the standard filesystem library, or the experimental filesystem library from the technical specification, but you must not mix them together. If you're targeting C++17, then you should use <filesystem>.

I will get the error that filesystem: No such file or directory

The ideal solution is to upgrade your compiler to a version that has non-experimental support for C++17. Otherwise use the experimental TS or Boost.

Solution 2

It seems your C++17 compiler doesn't include the standard filesystem header. One possible way to get around that:

#ifndef __has_include
  static_assert(false, "__has_include not supported");
#else
#  if __cplusplus >= 201703L && __has_include(<filesystem>)
#    include <filesystem>
     namespace fs = std::filesystem;
#  elif __has_include(<experimental/filesystem>)
#    include <experimental/filesystem>
     namespace fs = std::experimental::filesystem;
#  elif __has_include(<boost/filesystem.hpp>)
#    include <boost/filesystem.hpp>
     namespace fs = boost::filesystem;
#  endif
#endif

Then use fs:: instead of std::filesystem:: everywhere.

Checking __cplusplus >= 201703L is just an extra precaution if you want to use filesystem when using C++11/14. In those cases, __has_include(<filesystem>) may be true but including it will not define the std::filesystem namespace.

Share:
21,008
Sean
Author by

Sean

Updated on June 25, 2021

Comments

  • Sean
    Sean almost 3 years

    I have checked a lot of issues about the link of filesystem under c++17 and I still cannot make the link successfully. My main.cpp file is as the following.

    #include <experimental/filesystem>
    
    
    int main(int argc, char** argv)
    {
        std::string imageDirectory = "./image";;
        std::vector<std::string> imagePath;
    
        for (const auto& entry: std::filesystem::directory_iterator(imageDirectory))
        {
            imagePath.push_back(entry.path());
            std::cout << entry.path() << std::endl;
        }
    
        return 0;
    }
    

    My CMakeLists.txt is as the following.

    cmake_minimum_required(VERSION 3.8 FATAL_ERROR)
    
    project(visual_hull LANGUAGES CXX)
    set(CMAKE_CXX_STANDARD 17)
    add_library(dataIO
            STATIC
                dataIO.hpp
                dataIO.cpp)
    
    find_package(OpenCV REQUIRED core highgui imgproc)
    
    target_link_libraries(dataIO ${OpenCV_LIBS})
    
    add_executable(visual_hull main.cpp)
    
    target_link_libraries(visual_hull PUBLIC dataIO
                                             stdc++fs)
    

    The error is as the following.

    /home/SENSETIME/zhangshunkang/Downloads/programming/c++/visual_hull/main.cpp: In function ‘int main(int, char**)’:
    /home/SENSETIME/zhangshunkang/Downloads/programming/c++/visual_hull/main.cpp:15:31: error: ‘std::filesystem’ has not been declared
      for (const auto& entry: std::filesystem::directory_iterator(imageDirectory))
                                   ^
    CMakeFiles/visual_hull.dir/build.make:62: recipe for target 'CMakeFiles/visual_hull.dir/main.cpp.o' failed
    make[2]: *** [CMakeFiles/visual_hull.dir/main.cpp.o] Error 1
    CMakeFiles/Makefile2:72: recipe for target 'CMakeFiles/visual_hull.dir/all' failed
    make[1]: *** [CMakeFiles/visual_hull.dir/all] Error 2
    Makefile:83: recipe for target 'all' failed
    make: *** [all] Error 2