On 29 September 2022 20:25:06 BST, Edward Catmur <ecatmur@googlemail.com> wrote:
>On Thu, 29 Sept 2022 at 18:15, Lénárd Szolnoki via Std-Proposals <std-proposals@lists.isocpp.org> 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.
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.)
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...
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
my $.02,
Arthur