Amaterasu
Amaterasu

Reputation: 396

Use boost::filesystem with std::ifstream?

I'm using Ubuntu 20.04 LTS with C++ 20 and boost 1.71.0.

The following compiles without error and outputs the sample file content:

#include <iostream>
#include <string>
#include <boost/filesystem.hpp>
#include <filesystem>

int main() {
    boost::filesystem::path output_dir = boost::filesystem::path("/out/");
    boost::filesystem::path sample_file = output_dir / "sample.txt";
    std::ifstream ifs{sample_file};
    std::string content((std::istreambuf_iterator<char>(ifs)), (std::istreambuf_iterator<char>()));
    std::cout << "Sample file content: " << std::endl << content << std::endl;
    return 0;
}

So how does this work? Is this boost::filesystem::path implicitly cast to std::string?

Is this safe to use?

Upvotes: 2

Views: 524

Answers (2)

Alan Birtles
Alan Birtles

Reputation: 36488

std::basic_fstream has a constructor which takes a templated FSPath type https://en.cppreference.com/w/cpp/io/basic_ifstream/basic_ifstream

This overload should only accept std::filesystem::path but it looks like libstdc++ accepts any class which conforms to std::filesystem::path's interface. This is non-standard and doesn't compile with other standard libraries: https://godbolt.org/z/njr5s3har

You can fix this with the boost/filesystem/fstream.hpp header, but you'll have to change std::ifstream to boost::filesystem::fstream. A better fix is to just change to using std::filesystem which is mostly a drop in replacement for boost::filesystem.

Upvotes: 2

Anya Shenanigans
Anya Shenanigans

Reputation: 94799

The documentation for Boost Filesystem fstream indicates:

The C++ Standard Library's header uses const char* to pass arguments representing file names, with that usage occurring seven times.

The Filesystem Library's fstream.hpp header provides equivalent components, in namespace boost::filesystem, except that the seven const char* arguments have been replaced by const path& arguments.

The Filesystem Library's fstream.hpp header simply uses the standard library components as base classes, and then redeclares constructors and open functions to take arguments of type const path& instead of const char*.

It's documented use is in the 2 minute tutorial, and the examples.

Upvotes: 2

Related Questions