C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Proposal to allow multiple template parameters packs of different types

From: Anoop Rana <ranaanoop986_at_[hidden]>
Date: Mon, 14 Nov 2022 23:37:58 +0530
> Ts=<int,int>, Us=<> , but as far as I could tell, Anoop rejects that
outcome.

Note that I don't actually reject `Ts={int, int}`, `Us={ }`. What I am
objecting is that the program 1.1 is ill-formed *with `U` not being { } *as
per the current wording instead of being

*1)* well-formed with `Ts={int, int}`, `Us={ }` assuming packs are
greedy(no ambiguity) or
*2) *ill-formed with `Ts={int, int}`, `Us={ }` assuming this is ambiguous
instead of being greedy or
*3) *ill-formed with `Ts={int, int}`, `Us={}` assuming packs are greedy(no
ambiguity). If this point 3 is what the standard currently supports then it
doesn't make sense because a parameter pack is allowed to be empty so that
Ts={int, int}, Us={ } is an expected output and the program should be
well-formed instead of ill-formed. Note again that Ts={int, int}, Us={ } is
an expected output in this point 3 because there is no ambiguity
interpretation used here in this point. These interpretations are separate
from each other as also noted below.

--------------------------------

> Anoop's paper *seems* to be suggesting that this should become greedy
thus unambiguously Ts=<int,int>, Bs=<>, Us=<>.

No, no, no... That is not what I am saying at all in my paper. The example
that you gave ` template<class... Ts, bool... Bs, class... Us> void f();
f<int, int>();` *should be ill-formed according to my paper. *In the above
quoted example the template parameter `Us` is of the same underlying type
as `Ts` and so this is ill-formed.

--------------------------------

*> *It *asserts* that the status quo "doesn't make sense,"

I say that it "doesn't make sense" because the aim of the paper is to
handle cases consistently and intuitively and above all logically. I've
added two more examples in my revised paper named *PnnnnR1.pdf *attached at
the end of this email. One example is the one that *Arthur *gave. The other
added example is to make more clear the intention of the paper as I
think(by reading arthur's comment about consistency) that some things were
unclear.

*NOTE:*

Just to sum up some things, according to the paper `template<typename... T,
typename... U> f(){}` is ill-formed because `U` and `T` have the same
underlying types(meaning they both are "type" parameter packs) and thus
when making a call like `f<int, int>();` there is ambiguity. Note this is
the essential difference here. The program is ill-formed due to ambiguity
and not due to greediness of a pack. That is, because there are multiple
options available and no way to which argument should match which parameter
pack's sequence.

The paper also notes that instead of choosing the ambiguity
interpretation(which we prefer over IGPs), the other option is to add a
separate clause in the standard saying that the packs are greedy and that
the error is not due to any ambiguity. Basically, these two interpretations
are separate from each other and the standard should clarify which of the
two(or if both) the standard supports and if the program
`template<typename... T, typename... U> void f(){}` is ill-formed due to
interpretation 1(greedy packs) or interpretation 2(ambiguity) or due to
both interpretations. In case ``template<typename... T, typename... U> void
f(){}` is ill-formed due to IGPs then it wouldn't make sense because the
parameter pack U is allowed to be an empty pack and so the more
natural/logical outcome is for the program to be well-formed. *This boils
down to* saying that the 2nd option for the standard is to make the
program ``template<typename... T, typename... U> void f(){}; f<int,int>();`
well-formed with T={int,int} and U ={ }.


Below is the revised document(revision 1) of the same. Thanks for giving
your input. I appreciate it and will add more examples clearing any
misunderstandings of what is being presented in the paper(if any) or my
mistakes(if any) in the document.

Regards,
Anoop Rana


On Mon, 14 Nov 2022 at 21:48, Arthur O'Dwyer <arthur.j.odwyer_at_[hidden]>
wrote:

> On Mon, Nov 14, 2022 at 8:48 AM Anoop Rana via Std-Proposals <
> std-proposals_at_[hidden]> wrote:
>
>> Attached is the proposal [...]
>>
>
> Section 1 (1.1, 1.2) points out the problem with
> template<class... Ts, class... Us> void f();
> f<int, int>();
> Is this Ts=<>, Us=<int,int>? or Ts=<int>, Us=<int>? or Ts=<int,int>, Us=<>?
> Today it is ambiguous (i.e. ill-formed). Anoop's paper section 1.2
> mentions the possibility of making it greedy thus unambiguously
> Ts=<int,int>, Us=<>, but as far as I could tell, Anoop rejects that outcome.
>
> But then consider this code:
> template<class... Ts, bool... Bs, class... Us> void f();
> f<int, int>();
> Is this Ts=<>, Bs=<>, Us=<int,int>? or Ts=<int>, Bs=<>, Us=<int>? or
> Ts=<int,int>, Bs=<>, Us=<>?
> Today it is ambiguous (i.e. ill-formed). Anoop's paper *seems* to be
> suggesting that this should become greedy thus unambiguously Ts=<int,int>,
> Bs=<>, Us=<>.
> But why should this case be any greedier than the previous case? They
> should be handled *consistently*, one way or the other. I think the
> current Standard *does* handle them consistently; we should break that
> consistency only with a really good reason.
>
> Speaking of "good reason": the paper offers no motivation for this change
> at all. It *asserts* that the status quo "doesn't make sense," but
> doesn't present any problems caused by the status quo, either in terms of
> "I can't write this useful code" or "I can't teach this effectively" or
> whatever. Without motivation, a change of this magnitude should have a
> strong presumption of being-rejected.
> Section 3 is currently titled "Motivation and Scope," but it doesn't talk
> about motivation and doesn't really have to do with "scope" either. I think
> this was a cut-and-paste/template error.
>
> –Arthur
>

Received on 2022-11-14 18:08:11