C++ Logo


Advanced search

Re: [std-proposals] Make basic_string_view's range construction _conditionally_ explicit

From: Giuseppe D'Angelo <giuseppe.dangelo_at_[hidden]>
Date: Mon, 30 Jan 2023 12:55:25 +0100
Il 27/01/23 13:44, Jonathan Wakely via Std-Proposals ha scritto:
> On Fri, 27 Jan 2023 at 12:17, Giuseppe D'Angelo via Std-Proposals
> <std-proposals_at_[hidden] <mailto:std-proposals_at_[hidden]>>
> wrote:
> Hello,
> I'm working on a proposal that wants to "make string views usable
> again"
> as an interface type for read-only non-owning contiguous string data.
> Namely: re-enable their implicit conversion from any other compatible
> range class. P2499R0 made the conversion explicit, IMO damaging
> interoperability between string view classes. Applying P2499's change
> (make the range constructor explicit) to Qt's own string view classes
> caused quite some friction.
> I've posted a draft here:
> https://isocpp.org/files/papers/D2779R0.html
> <https://isocpp.org/files/papers/D2779R0.html>
> Any feedback is welcome.
> > If one uses |std::string s(200);| as a storage type instead of some
> other contiguous container (like |std::array<char, 200>|), then the
> example above would still have the problem of using the "wrong" size
> when |s| is converted to a |std::string_view|. The conversion from
> |std::string| to |std::string_view| remains however implicit.
> Yes, but you can resize the "storage" std::string before converting it
> to a string_view, so it does the right thing. You can't do that for the
> std::array example.

You can't resize an array, but you can build a shorter string_view out
of it (a string_view of the "actual size"). In either case (string and
array) you have to do an extra step after filling the storage; in other
words, you're *not* supposed to use a string_view built out of the
container "right away". So the original motivation looks more a band-aid
than a thorough fix.

> > Unless |my::string| itself provides an implicit conversion operator
> towards |std::string_view|,
> That was always the intended solution. That's why std::string_view
> doesn't have a constructor from std::string, but relies on std::string
> converting to std::string_view instead: because that's the pattern we
> expected user-defined strings to follow. We can't make std::string_view
> know about every string type out there, but they can know about
> std::string_view (because it's in the standard). The range constructor
> has changed the landscape though.

My understanding was that the range constructor was added to allow
complete interoperability between string/string view classes (from the
standard library and from 3rd parties), so to change the landscape
*significantly*. By making it explicit, it becomes just syntactic sugar.

Practically speaking, sticking to the idea of using only
`std::string_view` as the universal interface type is annoying;
libraries with richer string view types (Qt) will have to accept a
`std::string_view` and (almost) always immediately convert into their
own string view type to actually do useful stuff. This will raise the
question, why isn't the library using its own string views at the
interface level? Any solution involving template magic isn't practical
nor scalable. So here we are.

> > In Qt, the author implemented
> <https://isocpp.org/files/papers/D2779R0.html#biblio-qtpatch> the same
> semantic change of P2499R0 for Qt’s string view classes.
> That was your choice to "break" it in that way, copying
> std::string_view's constructor overload set isn't required ;-)


> I think Option 2 should be strongly considered as an alternative
> resolution to LWG 3857. Has it been implemented in a std::string_view
> implementation? I don't imagine any great difficulties, but it
> complicates the implementation slightly and will be a little slower to
> compile. If users *are* going to copy the API of string_view, including
> this constructor, then this change would require even more work to
> replicate the API.

Not yet; I hadn't had the time. to be honest, I don't expect any
challenge in its implementation. The question is really if a name as
generic as `traits_type` is acceptable or too risky.

Thank you for your feedback,

Giuseppe D'Angelo

Received on 2023-01-30 11:55:28