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