C++17’s std::filesystem gives me the warm fuzzy feeling Python3’s pathlib does. Easy, intuitive and cross-platform, yet another excuse to use C++17. Don’t look back. Just use it.

Specially useful functions in std::filesystem are:

The / operator : The committee fought their instincts to be “enterprise” , decided to be more Pythonic, and got this very right. The “/” operator will append path components together. Operands can be strings.

path.parent_path() / filename_as_string

.parent_path(): It does what it says on the tin. Again, correctly done.

fs::relative : It will compute a path relative to another. However I found that for most of my uses, simply concatenating a relative path string to the base path worked as expected.

fs::absolute, fs::canonical and fs::weakly_canonical : These are related, but importantly different. They all convert the given relative path to an absolute path.

fs::absolute will leave in any dot and dot-dot elements in the path. So you end up with things like /Users/kghose/Code/groho/debug_build/../../tests/groho-test-data/de432s.bsp

fs::canonical converts the given relative path to an absolute path that has no dot, dot-dot elements or symbolic links in its generic format representation. However, it will throw an exception if the path doesn’t exist.

fs::weakly_canonical does the same as fs::canonical but doesn’t throw a hissy fit if some part of the path is missing. One use of this is to see what a relative path would resolve to even if the path does not exist.

Also super useful, and self-evident are: fs::exists, fs::create_directory and fs::create_directories. Seriously, this library is very user friendly.

Best of all, in the several places I changed code to use std::filesystem::path instead of std::string, it was just a drop in replacement. File stream operations that originally consumed std::string as the file name, will happily take path objects. Path objects sensibly convert to strings when printing out.

Yet another excuse to use C++17. Don’t look back.