Topic: Protecting a function parameter pack from


Author: "'Johannes Schaub' via ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Date: Tue, 23 Aug 2016 09:00:26 +0200
Raw View
Unfortunately, "nondeduced" does not work here, because the pack
expansion is outside of it. Compilers appear to expand the pack before
deducing the elements:


template<typename ...T, class Z>
void f(void(nodeduced_t<T>..., Z)) { }

void g(int, char) { }

int main() {
   f<int>(g);
}

This will not compile, apparently compilers create "void(int,
nondeduced_t<T>, Z)" and try to compare "nondeduced_t<T>" against
"char". My "protected" prevents this "growing" of the parameter pack.

The case for "tuple<int>" refers to template argument deduction for
class templates, i.e "std::tuple t(10)". The problem with partially
specifying template arguments is that the deduction guide provides

    template<Outer ...T = <int, ...>>
    tuple(<int, Outer> &&... t);

And will extend "Outer" with whatever constructor arguments you pass
in. The "protected" would forbid this analog here. Perhaps here we can
put a workaround in terms of a trailing parameter pack, and put a
condition that causes an SFINAE check failure.. This would cause
deduction guides to not extend "Outer", but put the further args into
"SfinareCheck", later SFINAE-failing and not doing that deduction
(would that work??). But that's far from elegant, so I guess this is
not an option

    template<typename ...SfinaeCheck, typename
std::enable_if<sizeof...(SfinaeCheck)==0,int>::type=0>
    tuple(Outer &&... outers, SfinaeCheck &&...);

Apart from that, the workaround wouldn't work for the function pointer
case above anyway.

2016-08-23 3:16 GMT+02:00 TONGARI J <tongari95@gmail.com>:
> On Tuesday, August 23, 2016 at 4:21:25 AM UTC+8, Johannes Schaub wrote:
>>
>> Sometimes I would like to say "this function parameter pack must
>> either be all-explicitly-specified or all deduced", to forbid the
>> following and other (similar to how "nondeduced<..>::type" can disable
>> deduction for non-packs)
>>
>>     template<typename ...T>
>>     void f(T ...);
>>
>>     f<int>(1, 2); // oops
>>
>> This would come handy in class template arg deduction for std::tuple,
>> because "std::tuple<int> a(1, 2)" could be rejected. I would propose
>> "protected ..." to be a "non-extensible pack expansion":
>>
>>     template<typename ...T>
>>     void f(T protected ...);
>>
>>     f<int>(1, 2); // error!
>>
>> Similar, tuple's constructor can be defined as
>>
>>     tuple(Types && protected ... values);
>>
>> Do you like the idea?
>
>
> You have it already:
> template<class T>
> struct nodeduced
> {
>     using type = T;
> };
>
> template<class T>
> using nodeduced_t = typename nodeduced<T>::type;
>
> template<typename ...T, class...Z>
> void f(T ..., nodeduced_t<Z>...) {}
>
> And "std::tuple<int> a(1, 2)" is already rejected, I don't see your point.
>
> --
> You received this message because you are subscribed to the Google Groups
> "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> To view this discussion on the web visit
> https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/6dda12e3-acbd-40ab-ae5d-afe538fbf308%40isocpp.org.

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CANu6V4VOwu9QV8AgaCgqtBvZ5S8EbDnoY0xKpBQiuFWw7qJ1Kg%40mail.gmail.com.

.


Author: TONGARI J <tongari95@gmail.com>
Date: Tue, 23 Aug 2016 02:46:36 -0700 (PDT)
Raw View
------=_Part_8268_357413504.1471945596826
Content-Type: multipart/alternative;
 boundary="----=_Part_8269_1301464906.1471945596827"

------=_Part_8269_1301464906.1471945596827
Content-Type: text/plain; charset=UTF-8

On Tuesday, August 23, 2016 at 3:00:29 PM UTC+8, Johannes Schaub wrote:
>
> Unfortunately, "nondeduced" does not work here, because the pack
> expansion is outside of it. Compilers appear to expand the pack before
> deducing the elements:
>
>
> template<typename ...T, class Z>
> void f(void(nodeduced_t<T>..., Z)) { }
>
> void g(int, char) { }
>
> int main() {
>    f<int>(g);
> }
>
> This will not compile, apparently compilers create "void(int,
> nondeduced_t<T>, Z)" and try to compare "nondeduced_t<T>" against
> "char". My "protected" prevents this "growing" of the parameter pack.
>

What are you trying to do with this example?
Doesn't the code I show you already prevent the growing of the parameter
pack?

template<typename ...T, class... Z>
void f(void(T..., nodeduced_t<Z>...)) { }


void g(int, char) { }


int main() {
   f<int>(g); // error, partially specified

   f<int, char>(g); // ok, fully specified
}


> The case for "tuple<int>" refers to template argument deduction for
> class templates, i.e "std::tuple t(10)". The problem with partially
> specifying template arguments is that the deduction guide provides
>
>     template<Outer ...T = <int, ...>>
>     tuple(<int, Outer> &&... t);
>

I haven't seen this syntax before and I believe it's not valid C++17.
Template argument deduction for constructors cannot be partially specified.
There's no problem need to be solved.

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/83704294-59b0-4cd9-ad57-bf3b142b87f8%40isocpp.org.

------=_Part_8269_1301464906.1471945596827
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Tuesday, August 23, 2016 at 3:00:29 PM UTC+8, Johannes =
Schaub wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-le=
ft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">Unfortunately, &q=
uot;nondeduced&quot; does not work here, because the pack
<br>expansion is outside of it. Compilers appear to expand the pack before
<br>deducing the elements:
<br>
<br>
<br>template&lt;typename ...T, class Z&gt;
<br>void f(void(nodeduced_t&lt;T&gt;..., Z)) { }
<br>
<br>void g(int, char) { }
<br>
<br>int main() {
<br>=C2=A0 =C2=A0f&lt;int&gt;(g);
<br>}
<br>
<br>This will not compile, apparently compilers create &quot;void(int,
<br>nondeduced_t&lt;T&gt;, Z)&quot; and try to compare &quot;nondeduced_t&l=
t;T&gt;&quot; against
<br>&quot;char&quot;. My &quot;protected&quot; prevents this &quot;growing&=
quot; of the parameter pack.
<br></blockquote><div><br></div><div>What are you trying to do with this ex=
ample?</div><div>Doesn&#39;t the code I show you already prevent the growin=
g=C2=A0of the parameter pack?</div><div><br></div><div><div class=3D"pretty=
print" style=3D"border: 1px solid rgb(187, 187, 187); word-wrap: break-word=
; background-color: rgb(250, 250, 250);"><code class=3D"prettyprint"><div c=
lass=3D"subprettyprint"><span style=3D"color: #008;" class=3D"styled-by-pre=
ttify">template</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">&lt;</span><span style=3D"color: #008;" class=3D"styled-by-prettify">t=
ypename</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">...</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify">T</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" =
class=3D"styled-by-prettify">class</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">...</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> Z</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">&gt;</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"><br></span><span style=3D"color: #008;" class=3D"styled-by-prettify">voi=
d</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> f</span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span sty=
le=3D"color: #008;" class=3D"styled-by-prettify">void</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify">T</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">...,</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> nodeduced_t</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">&lt;</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify">Z</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">&gt;...))</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span=
 style=3D"color: #660;" class=3D"styled-by-prettify">}</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"><br><br><br></span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">void</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> g</span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">(</span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">int</span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">c=
har</span><span style=3D"color: #660;" class=3D"styled-by-prettify">)</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">}</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br><br><br></span><span style=3D"color: #008;" cla=
ss=3D"styled-by-prettify">int</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> main</span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">()</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =
=C2=A0f</span><span style=3D"color: #080;" class=3D"styled-by-prettify">&lt=
;int&gt;</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify">g</span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">);</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #800;" class=3D"styled-by-prettify">// error, partially specified</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"><br><br>=C2=A0 =C2=
=A0f</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</=
span><span style=3D"color: #008;" class=3D"styled-by-prettify">int</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #008;" class=3D"styled-by-prettify">char</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">&gt;(</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify">g</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">);</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> </span><span style=3D"color: #800;" class=3D"styled-by-prettify"=
>// ok, fully</span><span style=3D"color: rgb(136, 0, 0);"><span style=3D"c=
olor: #800;" class=3D"styled-by-prettify"> specified</span></span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">}</span></div></code></div></div=
><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;marg=
in-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">The case for=
 &quot;tuple&lt;int&gt;&quot; refers to template argument deduction for
<br>class templates, i.e &quot;std::tuple t(10)&quot;. The problem with par=
tially
<br>specifying template arguments is that the deduction guide provides
<br>
<br>=C2=A0 =C2=A0 template&lt;Outer ...T =3D &lt;int, ...&gt;&gt;
<br>=C2=A0 =C2=A0 tuple(&lt;int, Outer&gt; &amp;&amp;... t);
<br></blockquote><div><br></div><div>I haven&#39;t seen this syntax before =
and I believe it&#39;s not valid C++17.</div><div>Template argument deducti=
on for constructors cannot be partially specified. There&#39;s no problem n=
eed to be solved.</div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/83704294-59b0-4cd9-ad57-bf3b142b87f8%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/83704294-59b0-4cd9-ad57-bf3b142b87f8=
%40isocpp.org</a>.<br />

------=_Part_8269_1301464906.1471945596827--

------=_Part_8268_357413504.1471945596826--

.


Author: TONGARI J <tongari95@gmail.com>
Date: Tue, 23 Aug 2016 06:29:00 -0700 (PDT)
Raw View
------=_Part_8472_1072938865.1471958940576
Content-Type: multipart/alternative;
 boundary="----=_Part_8473_1308983685.1471958940577"

------=_Part_8473_1308983685.1471958940577
Content-Type: text/plain; charset=UTF-8

On Tuesday, August 23, 2016 at 5:46:36 PM UTC+8, TONGARI J wrote:
>
> On Tuesday, August 23, 2016 at 3:00:29 PM UTC+8, Johannes Schaub wrote:
>>
>> Unfortunately, "nondeduced" does not work here, because the pack
>> expansion is outside of it. Compilers appear to expand the pack before
>> deducing the elements:
>>
>>
>> template<typename ...T, class Z>
>> void f(void(nodeduced_t<T>..., Z)) { }
>>
>> void g(int, char) { }
>>
>> int main() {
>>    f<int>(g);
>> }
>>
>> This will not compile, apparently compilers create "void(int,
>> nondeduced_t<T>, Z)" and try to compare "nondeduced_t<T>" against
>> "char". My "protected" prevents this "growing" of the parameter pack.
>>
>
> What are you trying to do with this example?
>

Ah, so you want to deduce `Z` but have `T...` explicitly specified in that
example, right?
It's strange that the following works but the above example doesn't...`Z`
somehow becomes non-deducible.
template<typename ...T>
void f(void(nodeduced_t<T>..., char)) { }

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/5aceab3e-d3e6-42b0-a735-846405f33633%40isocpp.org.

------=_Part_8473_1308983685.1471958940577
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Tuesday, August 23, 2016 at 5:46:36 PM UTC+8, TONGARI J=
 wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.=
8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr">On Tue=
sday, August 23, 2016 at 3:00:29 PM UTC+8, Johannes Schaub wrote:<blockquot=
e class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px=
 #ccc solid;padding-left:1ex">Unfortunately, &quot;nondeduced&quot; does no=
t work here, because the pack
<br>expansion is outside of it. Compilers appear to expand the pack before
<br>deducing the elements:
<br>
<br>
<br>template&lt;typename ...T, class Z&gt;
<br>void f(void(nodeduced_t&lt;T&gt;..., Z)) { }
<br>
<br>void g(int, char) { }
<br>
<br>int main() {
<br>=C2=A0 =C2=A0f&lt;int&gt;(g);
<br>}
<br>
<br>This will not compile, apparently compilers create &quot;void(int,
<br>nondeduced_t&lt;T&gt;, Z)&quot; and try to compare &quot;nondeduced_t&l=
t;T&gt;&quot; against
<br>&quot;char&quot;. My &quot;protected&quot; prevents this &quot;growing&=
quot; of the parameter pack.
<br></blockquote><div><br></div><div>What are you trying to do with this ex=
ample?</div></div></blockquote><div><br></div><div>Ah, so you want to deduc=
e `Z` but have `T...` explicitly specified in that example, right?</div><di=
v>It&#39;s strange that the following works but the above example doesn&#39=
;t...`Z` somehow becomes non-deducible.</div><div><div class=3D"prettyprint=
" style=3D"border: 1px solid rgb(187, 187, 187); word-wrap: break-word; bac=
kground-color: rgb(250, 250, 250);"><code class=3D"prettyprint"><div class=
=3D"subprettyprint"><span style=3D"color: #008;" class=3D"styled-by-prettif=
y">template</span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>&lt;</span><span style=3D"color: #008;" class=3D"styled-by-prettify">typen=
ame</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">...</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify">T</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">&gt;</span><span style=3D"color:=
 #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #008;=
" class=3D"styled-by-prettify">void</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"> f</span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">(</span><span style=3D"color: #008;" class=3D"styled-by-pr=
ettify">void</span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">nodeduc=
ed_t</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify">T</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">&gt;...,</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"=
color: #008;" class=3D"styled-by-prettify">char</span><span style=3D"color:=
 #660;" class=3D"styled-by-prettify">))</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">}</span></div></code></div><div><br></div></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/5aceab3e-d3e6-42b0-a735-846405f33633%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/5aceab3e-d3e6-42b0-a735-846405f33633=
%40isocpp.org</a>.<br />

------=_Part_8473_1308983685.1471958940577--

------=_Part_8472_1072938865.1471958940576--

.


Author: "'Johannes Schaub' via ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Date: Tue, 23 Aug 2016 15:32:03 +0200
Raw View
2016-08-23 15:29 GMT+02:00 TONGARI J <tongari95@gmail.com>:
> On Tuesday, August 23, 2016 at 5:46:36 PM UTC+8, TONGARI J wrote:
>>
>> On Tuesday, August 23, 2016 at 3:00:29 PM UTC+8, Johannes Schaub wrote:
>>>
>>> Unfortunately, "nondeduced" does not work here, because the pack
>>> expansion is outside of it. Compilers appear to expand the pack before
>>> deducing the elements:
>>>
>>>
>>> template<typename ...T, class Z>
>>> void f(void(nodeduced_t<T>..., Z)) { }
>>>
>>> void g(int, char) { }
>>>
>>> int main() {
>>>    f<int>(g);
>>> }
>>>
>>> This will not compile, apparently compilers create "void(int,
>>> nondeduced_t<T>, Z)" and try to compare "nondeduced_t<T>" against
>>> "char". My "protected" prevents this "growing" of the parameter pack.
>>
>>
>> What are you trying to do with this example?
>
>
> Ah, so you want to deduce `Z` but have `T...` explicitly specified in that
> example, right?
> It's strange that the following works but the above example doesn't...`Z`
> somehow becomes non-deducible.
> template<typename ...T>
> void f(void(nodeduced_t<T>..., char)) { }
>

This works because you never try to call "f" with anything.

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CANu6V4XoPDywfs1gg3ffy4%3DY12ifqN9ktRyq8ZqprLzZXt_MVA%40mail.gmail.com.

.