Date: Thu, 29 Sep 2022 16:44:14 -0400
On Thu, Sep 29, 2022 at 3:57 PM Lénárd Szolnoki via Std-Proposals <
std-proposals_at_[hidden]> wrote:
> On 29 September 2022 20:25:06 BST, Edward Catmur <ecatmur_at_[hidden]>
> wrote:
> >On Thu, 29 Sept 2022 at 18:15, Lénárd Szolnoki via Std-Proposals <
> 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.
*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
std-proposals_at_[hidden]> wrote:
> On 29 September 2022 20:25:06 BST, Edward Catmur <ecatmur_at_[hidden]>
> wrote:
> >On Thu, 29 Sept 2022 at 18:15, Lénárd Szolnoki via Std-Proposals <
> 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.
*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
Received on 2022-09-29 20:44:26