Document number: D0000R0
Date: 2019-05-28
Project: WG21, Library Working Group
Author: Charles Milette [email protected]
This proposal allows assigning a type convertible to a std::string_view
to a std::filesystem::path
.
Note: text in this proposal assumes that std::string_view
matches std::filesystem::path::value_type
to avoid retyping std::basic_string_view<std::filesystem::path::value_type>
frequently.
One of the many uses of std::string_view
and its different encoding friends is to provide a common interface to the countless string types provided by the many frameworks or libraries out there. This way, one can write their string manipulation functions so that it can be called with either a std::string
, winrt::hstring
(a string type in Microsoft’s C++/WinRT library) or another std::string_view
without writing templates (solution which doesn’t works easily when said string types have a different interface), or duplicating code (violating DRY).
Thanks to implicit conversion taking place, this establishes a two-way "I don't care" relationship, where the caller does not needs to care about the callee using std::string_view
, and the callee does not needs to care about the caller using a third-party string type. This relationship is what gives std::string_view
its power to allow easily writing universal, elegant, fast and non-copying APIs when pertaining to strings.
Currently, [fs.path.req]
is worded so that only std::basic_string_view<EcharT, traits>
itself is accepted, and not types convertible to it, which makes assigning a std::filesystem::path
from those types either an error or a not so nice line. It breaks that two-way relationship, because the caller needs to care about std::filesystem::path
needing std::string_view
due to implicitly convertible types not being allowed.
#include <filesystem>
#include <string_view>
// Provided for demonstration purposes, a real custom string type would be more complete.
struct custom_string
{
operator std::string_view() const
{
return "/home/JohnDoe/Documents";
}
};
int main()
{
std::filesystem::path path;
custom_string str;
std::string_view view = str;
path = view; // ok
path = str; // error
path = static_cast<std::string_view>(str); // ok
}
Another point for this is that std::filesystem::path
can be considered as a special version of std::string
destined for file paths (as shown by members like operator string_type
that allows better interoperability with older code). If the variable path in the previous example where to be a std::string
, the line where an error occurs would be well-formed. As such, to keep consistency between the two standard library types, the operation should be allowed on std::filesystem::path
.
This proposal only affects one standard library class and header.
I do not believe that the suggested change would cause any breakage, because all existing valid inputs will still be accepted, this proposal only adds more possible inputs:
std::basic_string
will be handled by its convertibility tostd::basic_string_view
;- Passing a
std::basic_string_view
directly will still work; - Pointers to null-terminated strings or arrays are also still accepted, because they can either convert to
std::basic_string_view
or are valid input iterators; - Finally, input iterators are unchanged.
???