This page is a snapshot from the LWG issues list, see theLibrary Active Issues List for more information and the meaning ofC++17 status.
filesystem::path overloads forFile-based streamsSection: 31.10[file.streams]Status:C++17Submitter: Beman DawesOpened: 2016-03-16Last modified: 2017-07-30
Priority:2
View all otherissues in [file.streams].
View all issues withC++17 status.
Discussion:
The constructor andopen functions forFile-based streams in 27.9 [file.streams] currently provide overloads forconst char* andconst string& arguments that specify the path for the file to be opened. With the addition of the File System TS to the standard library, these constructors andopen functions need to be overloaded for const filesystem::path& so that file-based streams can take advantage of classfilesystem::path features such as support for strings of character typeswchar_t,char16_t, andchar32_t.
The const filesystem::path& p overload for these functions is like the existingconst string& overload; it simply calls the overload of the same function that takes a C-style string.
For operating systems like POSIX that traffic inchar strings for filenames, nothing more is required. For operating systems like Windows that traffic inwchar_t strings for filenames, an additional C-style string overload is required. The overload's character type needs to be specified asstd::filesystem::path::value_type to also support possible future operating systems that traffic inchar16_t orchar32_t characters.
Not recommended:
Given the proposed constructor andopen signatures takingconst filesystem::path&, it would in theory be possible to remove some of the other signatures. This is not proposed because it would break ABI's, break user code depending on user-defined automatic conversions to the existing argument types, and invalidate existing documentation, books, and tutorials.
Implementation experience:
The Boost Filesystem library has provided header<boost/filesystem/fstream.hpp> implementing the proposed resolution for over a decade.
The Microsoft/Dinkumware implementation of standard library header<fstream> has provided theconst wchar_t* overloads for many years.
[2016-08-03 Chicago]
Fri PM: Move to Review
Proposed resolution:
At the end of 27.9.1 File streams [fstreams] add a paragraph:
In this subclause, member functions taking arguments ofconst std::filesystem::path::value_type* shall only be provided on systems wherestd::filesystem::path::value_type ([fs.class.path]) is notchar. [Note: These functions enable classpath support for systems with a wide native path character type, such aswchar_t. —end note]
Change 27.9.1.1 Class template basic_filebuf [filebuf] as indicated:
basic_filebuf<charT,traits>* open(const char* s, ios_base::openmode mode);basic_filebuf<charT,traits>* open(const std::filesystem::path::value_type* s,ios_base::openmode mode); // wide systems only; see [fstreams] basic_filebuf<charT,traits>* open(const string& s, ios_base::openmode mode);basic_filebuf<charT,traits>* open(const filesystem::path& p,ios_base::openmode mode);
Change 27.9.1.4 Member functions [filebuf.members] as indicated:
basic_filebuf<charT,traits>* open(const char* s, ios_base::openmode mode);basic_filebuf<charT,traits>* open(const std::filesystem::path::value_type* s,ios_base::openmode mode); // wide systems only; see [fstreams]
To 27.9.1.4 Member functions [filebuf.members] add:
basic_filebuf<charT,traits>* open(const filesystem::path& p,ios_base::openmode mode);
Returns:
open(p.c_str(), mode);
Change 27.9.1.6 Class template basic_ifstream [ifstream] as indicated:
explicit basic_ifstream(const char* s, ios_base::openmode mode = ios_base::in);explicit basic_ifstream(const std::filesystem::path::value_type* s,ios_base::openmode mode = ios_base::in); // wide systems only; see [fstreams]explicit basic_ifstream(const string& s, ios_base::openmode mode = ios_base::in);explicit basic_ifstream(const filesystem::path& p,ios_base::openmode mode = ios_base::in);...void open(const char* s, ios_base::openmode mode = ios_base::in);void open(const std::filesystem::path::value_type* s,ios_base::openmode mode = ios_base::in); // wide systems only; see [fstreams]void open(const string& s, ios_base::openmode mode = ios_base::in);void open(const filesystem::path& p,ios_base::openmode mode = ios_base::in);
Change 27.9.1.7 basic_ifstream constructors [ifstream.cons] as indicated:
explicit basic_ifstream(const char* s, ios_base::openmode mode = ios_base::in);explicit basic_ifstream(const std::filesystem::path::value_type* s,ios_base::openmode mode = ios_base::in); // wide systems only; see [fstreams]
To 27.9.1.7 basic_ifstream constructors [ifstream.cons] add:
explicit basic_ifstream(const filesystem::path& p,ios_base::openmode mode = ios_base::in);
Effects:the same as
basic_ifstream(p.c_str(), mode).
Change 27.9.1.9 Member functions [ifstream.members] as indicated:
void open(const char* s, ios_base::openmode mode = ios_base::in);void open(const std::filesystem::path::value_type* s,ios_base::openmode mode = ios_base::in); // wide systems only; see [fstreams]
To 27.9.1.9 Member functions [ifstream.members] add:
void open(const filesystem::path& p,ios_base::openmode mode = ios_base::in);
Effects: calls
open(p.c_str(), mode).
Change 27.9.1.10 Class template basic_ofstream [ofstream] as indicated:
explicit basic_ofstream(const char* s, ios_base::openmode mode = ios_base::out);explicit basic_ofstream(const std::filesystem::path::value_type* s,ios_base::openmode mode = ios_base::out); // wide systems only; see [fstreams]explicit basic_ofstream(const string& s, ios_base::openmode mode = ios_base::out);explicit basic_ofstream(const filesystem::path& p,ios_base::openmode mode = ios_base::out);...void open(const char* s, ios_base::openmode mode = ios_base::out);void open(const std::filesystem::path::value_type* s,ios_base::openmode mode = ios_base::out); // wide systems only; see [fstreams]void open(const string& s, ios_base::openmode mode = ios_base::out);void open(const filesystem::path& p,ios_base::openmode mode = ios_base::out);
Change 27.9.1.11 basic_ofstream constructors [ofstream.cons] as indicated:
explicit basic_ofstream(const char* s, ios_base::openmode mode = ios_base::out);explicit basic_ofstream(const std::filesystem::path::value_type* s,ios_base::openmode mode = ios_base::out); // wide systems only; see [fstreams]
To 27.9.1.11 basic_ofstream constructors [ofstream.cons] add:
explicit basic_ofstream(const filesystem::path& p,ios_base::openmode mode = ios_base::out);
Effects:the same as
basic_ofstream(p.c_str(), mode).
Change 27.9.1.13 Member functions [ofstream.members] as indicated:
void open(const char* s, ios_base::openmode mode = ios_base::out);void open(const std::filesystem::path::value_type* s,ios_base::openmode mode = ios_base::out); // wide systems only; see [fstreams]
To 27.9.1.13 Member functions [ofstream.members] add:
void open(const filesystem::path& p,ios_base::openmode mode = ios_base::out);
Effects: calls
open(p.c_str(), mode).
Change 27.9.1.14 Class template basic_fstream [fstream] as indicated:
explicit basic_fstream(const char* s, ios_base::openmode mode = ios_base::in|ios_base::out);explicit basic_fstream(const std::filesystem::path::value_type* s,ios_base::openmode mode = ios_base::in|ios_base::out); // wide systems only; see [fstreams]explicit basic_fstream(const string& s, ios_base::openmode mode = ios_base::in|ios_base::out);explicit basic_fstream(const filesystem::path& p,ios_base::openmode mode = ios_base::in|ios_base::out);...void open(const char* s, ios_base::openmode mode = ios_base::in|ios_base::out);void open(const std::filesystem::path::value_type* s,ios_base::openmode mode = ios_base::in|ios_base::out); // wide systems only; see [fstreams]void open(const string& s, ios_base::openmode mode = ios_base::in|ios_base::out);void open(const filesystem::path& p,ios_base::openmode mode = ios_base::in|ios_base::out);
Change 27.9.1.15 basic_fstream constructors [fstream.cons] as indicated:
explicit basic_fstream(const char* s, ios_base::openmode mode = ios_base::in|ios_base::out);explicit basic_fstream(const std::filesystem::path::value_type* s,ios_base::openmode mode = ios_base::in|ios_base::out); // wide systems only; see [fstreams]
To 27.9.1.15 basic_fstream constructors [fstream.cons] add:
explicit basic_fstream(const filesystem::path& p,ios_base::openmode mode = ios_base::in|ios_base::out);
Effects:the same as
basic_fstream(p.c_str(), mode).
Change 27.9.1.17 Member functions [fstream.members] as indicated:
void open(const char* s, ios_base::openmode mode = ios_base::in|ios_base::out);void open(const std::filesystem::path::value_type* s,ios_base::openmode mode = ios_base::in|ios_base::out); // wide systems only; see [fstreams]
To 27.9.1.17 Member functions [fstream.members] add:
void open(const filesystem::path& p,ios_base::openmode mode = ios_base::in|ios_base::out);
Effects: calls
open(p.c_str(), mode).