Date: Fri, 30 Sep 2022 15:38:58 +0200
How about instead of giving "auto" the 100th new usage (just joking), use typename before an identifier to specify, that is should be deduced. This is similar as in template syntax. And instead of the "class" keyword there is less ambiguity with declaring a new class.
typename Arr<typename T, std::size_t N> arr = std::array<char, 10>{}; // Arr = std::array, T = char, N = 10
-----Ursprüngliche Nachricht-----
Von:Oleksandr Koval via Std-Proposals <std-proposals_at_[hidden]>
Gesendet:Fr 30.09.2022 15:30
Betreff:Re: [std-proposals] Named auto
An:std-proposals_at_[hidden];
CC:Oleksandr Koval <oleksandr.koval.dev_at_[hidden]>;
Follow up, I'd like eventually to be able to do this as well:
auto<class T, std::size_t N> arr = std::array<char, 10>{}; // T = char, N = 10
Just another argument that angle brackets should not be used to name the type of the `auto` itself. This however rises next question:
auto:[class Arr]<class T, std::size_t N> arr = std::array<char, 10>{}; // T = char, N = 10
should `Arr` be `std::array<char, 10>` or a template `std::array`? Probably the former but isn't that confusing?
On Fri, Sep 30, 2022 at 4:19 PM Oleksandr Koval <oleksandr.koval.dev_at_[hidden] <mailto:oleksandr.koval.dev_at_[hidden]> > wrote:
Sorry if this was already discussed, I like `auto<class T>` syntax but the problem I see is this:
std::vector<int> f();
auto<class T> v = f(); // should T be `std::vector<int>` or just `int`?
It’s a bit confusing when you see them side by side. Because of that I don’t think that using angle brackets is a good idea (at least I can’t find any form which is not confusing). We need a new syntax which will clearly show that typename(s) is closely related to `auto` itself. For example:
auto:[class T] v = f();
auto:[class T1, classT2] [key, value] = get_pair();
On Fri, Sep 30, 2022 at 4:07 AM Edward Catmur via Std-Proposals <std-proposals_at_[hidden] <mailto:std-proposals_at_[hidden]> > wrote:
On Thu, 29 Sept 2022 at 21:44, Arthur O'Dwyer <arthur.j.odwyer_at_[hidden] <mailto:arthur.j.odwyer_at_[hidden]> > wrote:
On Thu, Sep 29, 2022 at 3:57 PM Lénárd Szolnoki via Std-Proposals <std-proposals_at_[hidden] <mailto:std-proposals_at_[hidden]> > wrote:
On 29 September 2022 20:25:06 BST, Edward Catmur <ecatmur_at_[hidden] <mailto:ecatmur_at_[hidden]> > wrote:
>On Thu, 29 Sept 2022 at 18:15, Lénárd Szolnoki via Std-Proposals <std-proposals_at_[hidden] <mailto:std-proposals_at_[hidden]> > wrote:
>
>> I think this could be addressed by two distinct proposals.
>>
>> 1. allow placeholders to appear in any deduced context (std::vector<auto>)
>> 2. allow a placeholder to introduce a name (auto<class T>, auto<int i>
>> might appear as a deduced nttp)
>>
>> Then you can have your vector<auto<class T>> to deduce the value type and
>> introduce the name T for that.
>
>std::vector<auto> is problematic, because elsewhere auto means a value of
>unconstrained type (e.g. in template<auto>).
I disagree. auto is a placeholder for the type of the non-type parameter. If you don't omit the name, then that name refers to the value.
FWIW, I tend to agree with Lénárd here: `auto *p, std::unique_ptr<auto> q` seems quite reasonable to me.
Ye-esss; looking at the grammar; `auto` is always a placeholder-type-specifier, which is a simple-type-specifier, so it makes sense that it takes the place of a concrete (or inferred) type.
So Lénárd, I apologise; you're correct that in these contexts `auto` designates a type, not a value. I'm still trying to get my head round "template<auto> int f();", but the syntax is clear.
However, I foresee practical problems with allowing auto anywhere in a declaration. Consider
template<class T> void f(T t); // since C++98
template<class T> void g(decltype(T(1)) t); // since C++11
void f(auto t); // since C++20, equivalent to f #1
void g(decltype(auto(1)) t); // since C++23, not equivalent to g #1
Now, the `T` parameter to `g` is not deducible, so "obviously" the `auto` in g #2 doesn't mean the same thing as the `auto` in f #2. But are you sure we can teach that to the computer?
(Background: I teach that `auto` since C++14 has (like most C++ keywords) had two meanings: concrete type inference, as in auto x = 1, and templatey type deduction, as in [](auto x){}. The physical mechanisms behind, and consequences of, these two usages of `auto` are vastly different, although their human-level meaning is similar: "I don't want to bother with types; compiler, please figure it out." So if you see me talking about "inference" versus "deduction," or "the first meaning of auto" versus "the second meaning of auto," that's what I'm talking about.)
The deduction process is ultimately the same; both end up in temp.deduct.call. In an abbreviated function template or generic lambda, the deduction can be overridden by explicit template argument, but that's a relatively minor effect. And syntactically, they're the same; a decl-specifier of a decl-specifier-seq (of a function parameter or variable declaration); `auto` in a function return type or trailing return type has less in common, though I'd suppose you'd class that as inference. Still, I guess it's OK to teach it that way.
It would certainly not be reasonable to have a rule like "Try to interpret every `auto` as deduction, but if that would result in a non-deducible template parameter, then backtrack and assume it's inference instead." It would be reasonable to have a rule that boils down to "Inside the operand of a decltype or sizeof or array bound, the `auto` always means inference not deduction." But is `g` above the only problem case? Are there other corner cases where `auto` is already legal today, and/or we wouldn't want it to mean a template parameter?
void f(A<auto(int())>); // is this concrete A<0> or templatey A<T(int())>? I guess the type of A will disambiguate...
Currently a placeholder can appear as the decl-specifier of a function parameter, variable declaration, or template parameter or, as exactly one simple-type-specifier of a return or trailing return type, conversion function id, new expression's type id, or (`auto` only) as the type specifier of a functional cast. If these were relaxed, I think we'd probably be OK; you just go through inventing extra type template parameters and perform deduction as usual.
Also I don't think ambiguity *can* be an issue, or it would be already; there must be disambiguators in the syntax. Indeed, I have a strong suspicion that your `A<auto(int())>` is a most vexing parse.
Also consider that while
void h1(std::vector<auto, auto> v);
would work fine with Lénárd's proposed syntax,
void h2(std::array<auto, ??> a);
would not. That does seem mildly problematic. However, maybe it's consistent with C++20, which permits
template<class T> concept Integral = true;
template<Integral T> void ij(); // since C++20
but not
template<int N> concept Odd = true;
template<Odd N> void ij(); // error: Odd does not constrain a type
Yes, fair enough; this does conform to the grammar.
--
Std-Proposals mailing list
Std-Proposals_at_[hidden] <mailto:Std-Proposals_at_[hidden]>
https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
--
Regards,
Oleksandr Koval.
--
Regards,
Oleksandr Koval.
--
Std-Proposals mailing list
Std-Proposals_at_[hidden]
https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
Received on 2022-09-30 13:39:01