Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can std::ifstream and std::ofstream be used with a std::string_view filename argument?

Tags:

c++

c++23

I was surprised to find that the following code does not compile:

auto example_function(std::string_view filename) {

    std::fstream ofile(filename, std::ios_base::out | std::ios_base::binary);

    std::fstream ifile(filename, std::ios_base::in | std::ios_base::binary);
}

Both of these lines produce similar errors:

error: no matching function for call to ‘std::basic_fstream<char>::basic_fstream(std::string_view&, std::_Ios_Openmode)’
error: ‘class std::basic_string_view<char>’ has no member named ‘make_preferred’
= decltype(std::declval<_Path&>().make_preferred().filename())>

error: no matching function for call to ‘std::basic_fstream<char>::basic_fstream(std::string_view&, std::_Ios_Openmode)’
error: ‘class std::basic_string_view<char>’ has no member named ‘make_preferred’
= decltype(std::declval<_Path&>().make_preferred().filename())>

The constructor options include arguments of type const char* and std::string&.

I was surprised to find no option includes std::string_view. Is there any obvious reason why this was not included?

Is there a valid way to make this code compile? Converting from a std::string_view to const char* may not be particularly safe, since a std::string_view may not be null terminated at the end of its .size().

Creating a std::string, on the other hand, will cause an additional copy and allocation.

like image 553
FreelanceConsultant Avatar asked Oct 29 '25 08:10

FreelanceConsultant


1 Answers

The C++ committee explicitly decided that fstream should not be constructible from string_view: The underlying OS call needs a null-terminated string, an allocation is required to turn a string_view to a null-terminated string, and the committee wants this allocation to be explicit (instead of implicit in the fstream construction).

In 2017, std::fstream was actually made constructible from std::string_view, because they are constructible from std::filesystem::path, and the latter is convertible from std::string_view. But this is considered a defect in C++17, and got banned by LWG 3430.

like image 55
cpplearner Avatar answered Oct 31 '25 20:10

cpplearner



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!