Я использую Ubuntu 20.04 LTS с C++ 20 и версией Boost 1.71.0.
Следующий код компилируется без ошибок и выводит содержимое файла примера:
#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;
}
Так как же это работает? Это boost::filesystem::path
неявно приведено к std::string
?
Безопасно ли это использовать?
В документации Boost Filesystem fstream указано:
Заголовок стандартной библиотеки C++ использует
const char*
для передачи аргументов, представляющих имена файлов, причем такое использование происходит семь раз.
Заголовок
fstream.hpp
библиотеки файловой системы предоставляет эквивалентные компоненты в пространстве именboost::filesystem
, за исключением того, что семь аргументовconst char*
были заменены аргументамиconst path&
.
Заголовок
fstream.hpp
библиотеки файловой системы просто использует компоненты стандартной библиотеки в качестве базовых классов, а затем переобъявляет конструкторы и открытые функции, чтобы они принимали аргументы типаconst path&
вместоconst char*
.
Документированное использование описано в 2-минутном руководстве и в примерах.
Однако они не используют boost::filesystem::ifstream
, они используют std::ifstream
Док говорит : (5) participates in overload resolution only if FsPath is std::filesystem::path.
. Но в данном случае это неправда :/ поскольку FsPath
есть boost::filesystem::path
.
@MarekR этот ответ не является неправильным, вы можете использовать boost::filesystem::path
, чтобы открыть boost::filesystem::ifstream
, он просто не отвечает на этот вопрос, поскольку ОП использует std::ifstream
std::basic_fstream
имеет конструктор, который принимает шаблонный FSPath
тип https://en.cppreference.com/w/cpp/io/basic_ifstream/basic_ifstream
Эта перегрузка должна принимать только std::filesystem::path
, но похоже, что libstdc++ принимает любой класс , который соответствует интерфейсу std::filesystem::path . Это нестандартно и не компилируется с другими стандартными библиотеками: https://godbolt.org/z/njr5s3har
Вы можете исправить это с помощью заголовка boost/filesystem/fstream.hpp, но вам придется изменить std::ifstream
на boost::filesystem::fstream
. Лучшее решение — просто перейти на использование std::filesystem
, что в основном является заменой boost::filesystem
.
Дангит. Я как раз собирался ответить то же самое, но не нашел подходящих фраз. В любом случае вы получили мой голос.