On Tue, Oct 29, 2019 at 6:26 PM Gavin Lambert via Boost-users <boost-users@lists.boost.org> wrote:
On 30/10/2019 05:11, Zach Laine wrote:
>     - pattern if (x == npos) is now so common that is imho important to
>     preserve it
>
> The std::string/std::string_view API is the only place in the STL where
> the algorithms do not return the end of the half-open input range on
> failure.  That's really wonky.  I don't care about preserving it.

Returning end of range on failure is incredibly inconvenient (for the
consumer; granted it's usually more convenient for the algorithm
implementer), and I'd be happier if STL algorithms didn't do that either.

I see that as an unfortunate consequence of using generic iterators as
input parameters and return types, and not an otherwise desirable design
choice.

(ie. the STL algorithms do it because they couldn't do anything better.
string doesn't do it because it can do something better [since it knows
the iterator type and class, and can consequently choose to return
something other than an iterator].)

I heartily disagree, but I'm also very curious about this.  As an example, could you take one of the simple std algorithms (std::find would be a very simple candidate), and show its definition in the style you have in mind?
 
>     - for the sake of completeness the normalization type used at the text
>     level ought to be a policy parameter; although I do understand your
>     arguments against it I think it should be there even at the cost of
>     different text types being inoperable without conversions
>
>
> I disagree.  Policy parameters are bad for reasoning.  If I see a
> text::text, as things currently stand, I know that it is stored as a
> contiguous array of UTF-8, and that it is normalized FCC.  If I add a
> template parameter to control the normalization, I change the invariants
> of the type.  Types with different invariants should have different
> names.  To do otherwise is a violation of the single responsibility
> principle.

While I too dislike policy parameters as a general rule -- especially
defaulted policy parameters, since APIs have a tendency to only
implement one and not all (see: how many libraries use std::string
instead of being templated on std::basic_string, or use std::vector<T>
instead of being templated on an allocator)...

Technically speaking, a different policy parameter does form a different
type name and thus "types with different invariants should have
different names" is satisfied.

Yes, you got me.  I was speaking loosely, and referred to a template as if it were a type.  What I should have added was that a template's single responsibility should be to stamp out types that all model the same concept.  A policy-based template has a hard time doing that.  A policy-based template that stamps out strings with different invariants does not do that at all.

Zach