C++ Logo

std-proposals

Advanced search

Re: [std-proposals] [Resurrected Proposal] Concept introduces a typename

From: Михаил Найденов <mihailnajdenov_at_[hidden]>
Date: Sat, 6 May 2023 09:10:36 +0300
Updated the proposal, fixing typos and adding a section Details

There it is proposed to let function(Foo Bar) always mean argument Bar of
type Foo. In other words, to have a concept introduce a typename,
one will also have to have a parameter name (or __ of some sort) much like
it is with regular variables.

On Wed, May 3, 2023 at 5:27 AM Barry Revzin via Std-Proposals <
std-proposals_at_[hidden]> wrote:

>
>
> On Tue, May 2, 2023 at 11:37 AM Gašper Ažman via Std-Proposals <
> std-proposals_at_[hidden]> wrote:
>
>> I'd be strongly opposed to introducing a yet another syntax to introduce
>> dependent names. There's nothing wrong with current template-heads.
>>
>
> +1. Over time I've come to the position that the terse syntax
> (specifically Concept auto, not auto by itself) was not a good idea. It's
> just pretty rare that it's even viable - you pretty regularly need the
> type, have a multi-parameter constraint, want multiple parameters of the
> same type, or have a constraint that you can't express using the terse
> syntax. Occasionally I'll see something in our codebase that takes a
> "std::integral auto val" or something, and be mildly shocked that it
> worked.
>
> If we want to cut some characters, there is room for improvement in the
> longer syntax.
>
> To start with, the leading template keyword is unnecessary. This was
> pointed out during the terse concepts discussions. Declarations can't start
> with <, so it's unambiguous to both the compiler and the reader what this
> means:
>
> <class T> auto min(T const&, T const&) -> T const&;
>
> That's 9 (or 8, if you don't put the space) characters gone, with the
> added benefit that it starts becoming reasonable to fit a whole declaration
> on one line. This is still longer than the proposed syntax, but only
> marginally so:
>
> <Sortable S> void f(S x);
> void f(Sortable S x);
>
> And doesn't lead to any additional questions about what reusing the same
> identifier means in multiple parameters. The paper says:
>
> [](Number auto x, decltype(x) y) { } //< current
> [](Number N x, N y) { }` //< **proposed**
>
> Are those supposed to be equivalent? The former allows a call (1, 2L), the
> latter seems like it would require both parameters to be the same type,
> which we can already write in marginally more characters today:
>
> [](Number N x, N y)
> []<Number N>(N x, N y)
>
> What I'm suggesting just allows the same in function templates:
>
> auto gcd(integral T l, T r) - T;
> <integral T> auto gcd(T l, T r) -> T;
>
> Next, I would like to make the following claims:
>
>
> 1. Type template parameters are *overwhelmingly* more common than
> non-type or template template parameters.
> 2. Anonymous non-type template parameters are not especially valuable
> to support, and with the coming addition of _ as a placeholder, are a waste
> of syntax space.
>
> Put those together, and it offers the ability to drop typename/class. It's
> one of those weird things in C++ where we have two exact synonyms, so
> people have pointless (in the grand scheme of things) style discussions
> about which to use - typename conveys that it's any type, but class is
> shorter. Well, maybe just put neither:
>
> <T> auto min(T const&, T const&) -> T const&;
>
> The reason I bring up (2) is that today this could've meant an unnamed
> value of type T. It's not possible today, because you can't omit the
> template keyword today, but a similar transformation in lambdas is valid
> code today (well, at least writing <T> could be, it falls apart quickly
> after that):
>
> auto min = []<T>(T const& x, T const& y) -> T const& { ... }
>
> Omitting a name for a non-type template parameter is even less useful in
> lambdas than in function templates. You could *only* call it as
> f.operator()<1>() anyway? Making the user write that mess just to ignore
> the value seems very rude. Maybe we could reclaim the syntax.
>
> The reason for dropping class/typename is to also suggest another, more
> adventurous direction. Changing which side of the type we put the
> constraint on. That is:
>
> <T: integral> auto gcd(T l, T r) -> T;
> <V: view + forward_range> class some_range_adapter { ... };
>
> There are two, unrelated motivations for this ordering:
>
> First, It allows putting multiple constraint-ids in there, which does come
> up a lot, and it's a pretty clear way of doing so. We can fight over
> whether the grouping should be + or &&, or split the difference and call it
> &.
>
> Second, As more code moves to C++20, template-heads are becoming more
> ambiguous to the reader. Here's an example, what does this mean:
>
> template <Some Thing>
>
> What is Thing?
>
> - A type, constrained on the concept named Some?
> - A value, whose type is Some?
> - A value, whose type is some specialization of the class template
> Some, whose type will be deduced by CTAD?
>
> Non-type template parameters, now that they can be class types too, are
> going to steadily become more and more common. It'd be nice to have some
> differentiation for the reader.
>
> But even if we don't do this last part, dropping template/class/typename
> seems pretty nice.
>
> Barry
>
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>

Received on 2023-05-06 06:10:51