C++ Logo


Advanced search

Re: why does std::basic_string should accept an std::basic_string_view with the same charT and Traits

From: Jason McKesson <jmckesson_at_[hidden]>
Date: Mon, 14 Sep 2020 12:07:26 -0400
On Sun, Sep 13, 2020 at 9:47 AM Arthur O'Dwyer via Std-Proposals
<std-proposals_at_[hidden]> wrote:
> On Sun, Sep 13, 2020 at 8:17 AM Robert Behar via Std-Proposals <std-proposals_at_[hidden]> wrote:
>> currently I can't compare two strings with differing allocators.
> IIUC, you're complaining that
> https://godbolt.org/z/db9MWW
> std::string a;
> std::pmr::string b;
> return a == b;
> does not compile, whereas
> return a == std::string_view(b);
> does compile.
> Marshall Clow's P0805 "Comparing Containers" would have fixed this incidentally for std::vector == std::pmr::vector, as part of its larger motivation of fixing vector<int> == vector<long>.
> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0805r2.html
> But P0805 specifically says:
> > I have not suggested changes to basic_string, because it does not use lexicographical_compare, but delegates to a traits class.
> Also, P0805 seems to be motionless? The last update was in 2018, and it didn't go into C++20.
> From the private Committee notes, it appears to me that it collided head-on with C++20 Ranges' notion of "constrained algorithms," where you're not supposed to ever be able to compare T and U unless they have a common_reference type, which is not true for e.g. `int` and `long`.
> So it might be useful to provide a very limited fork of P0805 that
> - only permits different allocators, not different element types
> - includes basic_string as well as all the STL containers

To add further to this, the `common_reference` issue is fixable for
some types thanks to `span` and `string_view`. As it is currently
defined, `span<T, dynamic>` can act as the `common_reference` type for
any `std::array<T, *>`. Same goes for `basic_string_view<C, T>` and
any `basic_string<C, T, *>`.

The primary issue with moving further than this is the fact that
`common_reference` is required to be *implicitly convertible* from the
source types. We don't do this for `span` on arbitrary
`contiguous_range`s for obvious reasons. So basically, for each
container, there would have to be some standard-defined type whose
sole purpose is to act as the `common_reference` type for comparison
purposes. The name of this type can be queried, but its properties
ought to be meaningless other than the fact that it can be converted
to and perform comparisons.

And this contrivance makes it clear how annoying this whole
`common_reference` rigamarole is when all you want to do is make two
things that happen to be different types comparable.

Received on 2020-09-14 11:07:39