Topic: Explicit function template argument


Author: m.cencora@gmail.com
Date: Wed, 28 Nov 2018 00:36:54 -0800 (PST)
Raw View
------=_Part_2310_921556040.1543394214966
Content-Type: multipart/alternative;
 boundary="----=_Part_2311_638433238.1543394214966"

------=_Part_2311_638433238.1543394214966
Content-Type: text/plain; charset="UTF-8"

Hi,

is following code correct according to standard?
In other words do compilers correctly deduce Ts... parameter pack in
nthImpl3 as decltype(Ints)... as invoked in nthImpl2?

It seems to work with clang, and all but trunk gcc versions.

#include <type_traits>
#include <utility>

template <typename ...Ts, typename Head, typename ...Tail>
Head nthImpl3(Ts..., Head head, Tail ...);

template <std::size_t ...Ints, typename ...Ts>
auto nthimpl2(std::index_sequence<Ints...>, Ts ...ts)
-> decltype(nthImpl3<decltype(Ints)...>(ts...));


template <int N, typename ...Ts>
struct nth_impl
{
using type = decltype(nthimpl2(std::make_index_sequence<N>(), Ts{}...));
};

template <int N, typename ...Ts>
using nth_type = typename nth_impl<N, Ts...>::type;


static_assert(std::is_same<nth_type<0, float, bool, char>, float>());
static_assert(std::is_same<nth_type<1, float, bool, char>, bool>());
static_assert(std::is_same<nth_type<2, float, bool, char>, char>());


Regards,
Maciej

--
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/b5eb854b-3ddd-4173-b71e-f6ce85fd887c%40isocpp.org.

------=_Part_2311_638433238.1543394214966
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div>Hi,</div><div><br></div><div>is following code correc=
t according to standard?</div><div>In other words do compilers correctly de=
duce Ts... parameter pack in nthImpl3 as decltype(Ints)... as invoked in nt=
hImpl2?</div><div><br></div><div>It seems to work with clang, and all but t=
runk gcc versions.</div><div><br></div><div><div style=3D"color: #000000;ba=
ckground-color: #fffffe;font-family: Consolas, "><div><span style=3D"color:=
 #0000ff;">#include</span><span style=3D"color: #000000;"> &lt;type_traits&=
gt;</span></div><div><span style=3D"color: #0000ff;">#include</span><span s=
tyle=3D"color: #000000;"> &lt;utility&gt;</span></div><br><div><span style=
=3D"color: #0000ff;">template</span><span style=3D"color: #000000;"> &lt;</=
span><span style=3D"color: #0000ff;">typename</span><span style=3D"color: #=
000000;"> ...Ts, </span><span style=3D"color: #0000ff;">typename</span><spa=
n style=3D"color: #000000;"> Head, </span><span style=3D"color: #0000ff;">t=
ypename</span><span style=3D"color: #000000;"> ...Tail&gt;</span></div><div=
><span style=3D"color: #000000;">Head nthImpl3(Ts..., Head head, Tail ...);=
</span></div><br><div><span style=3D"color: #0000ff;">template</span><span =
style=3D"color: #000000;"> &lt;std::size_t ...Ints, </span><span style=3D"c=
olor: #0000ff;">typename</span><span style=3D"color: #000000;"> ...Ts&gt;</=
span></div><div><span style=3D"color: #0000ff;">auto</span><span style=3D"c=
olor: #000000;"> nthimpl2(std::index_sequence&lt;Ints...&gt;, Ts ...ts) </s=
pan></div><div><span style=3D"color: #000000;">    -&gt; </span><span style=
=3D"color: #0000ff;">decltype</span><span style=3D"color: #000000;">(nthImp=
l3&lt;</span><span style=3D"color: #0000ff;">decltype</span><span style=3D"=
color: #000000;">(Ints)...&gt;(ts...));</span></div><br><br><div><span styl=
e=3D"color: #0000ff;">template</span><span style=3D"color: #000000;"> &lt;<=
/span><span style=3D"color: #0000ff;">int</span><span style=3D"color: #0000=
00;"> N, </span><span style=3D"color: #0000ff;">typename</span><span style=
=3D"color: #000000;"> ...Ts&gt;</span></div><div><span style=3D"color: #000=
0ff;">struct</span><span style=3D"color: #000000;"> nth_impl</span></div><d=
iv><span style=3D"color: #000000;">{</span></div><div><span style=3D"color:=
 #000000;">    </span><span style=3D"color: #0000ff;">using</span><span sty=
le=3D"color: #000000;"> type =3D </span><span style=3D"color: #0000ff;">dec=
ltype</span><span style=3D"color: #000000;">(nthimpl2(std::make_index_seque=
nce&lt;N&gt;(), Ts{}...));</span></div><div><span style=3D"color: #000000;"=
>};</span></div><br><div><span style=3D"color: #0000ff;">template</span><sp=
an style=3D"color: #000000;"> &lt;</span><span style=3D"color: #0000ff;">in=
t</span><span style=3D"color: #000000;"> N, </span><span style=3D"color: #0=
000ff;">typename</span><span style=3D"color: #000000;"> ...Ts&gt;</span></d=
iv><div><span style=3D"color: #0000ff;">using</span><span style=3D"color: #=
000000;"> nth_type =3D </span><span style=3D"color: #0000ff;">typename</spa=
n><span style=3D"color: #000000;"> nth_impl&lt;N, Ts...&gt;::type;</span></=
div><br><br><div><span style=3D"color: #0000ff;">static_assert</span><span =
style=3D"color: #000000;">(std::is_same&lt;nth_type&lt;</span><span style=
=3D"color: #09885a;">0</span><span style=3D"color: #000000;">, </span><span=
 style=3D"color: #0000ff;">float</span><span style=3D"color: #000000;">, </=
span><span style=3D"color: #0000ff;">bool</span><span style=3D"color: #0000=
00;">, </span><span style=3D"color: #0000ff;">char</span><span style=3D"col=
or: #000000;">&gt;, </span><span style=3D"color: #0000ff;">float</span><spa=
n style=3D"color: #000000;">&gt;());</span></div><div><span style=3D"color:=
 #0000ff;">static_assert</span><span style=3D"color: #000000;">(std::is_sam=
e&lt;nth_type&lt;</span><span style=3D"color: #09885a;">1</span><span style=
=3D"color: #000000;">, </span><span style=3D"color: #0000ff;">float</span><=
span style=3D"color: #000000;">, </span><span style=3D"color: #0000ff;">boo=
l</span><span style=3D"color: #000000;">, </span><span style=3D"color: #000=
0ff;">char</span><span style=3D"color: #000000;">&gt;, </span><span style=
=3D"color: #0000ff;">bool</span><span style=3D"color: #000000;">&gt;());</s=
pan></div><div><span style=3D"color: #0000ff;">static_assert</span><span st=
yle=3D"color: #000000;">(std::is_same&lt;nth_type&lt;</span><span style=3D"=
color: #09885a;">2</span><span style=3D"color: #000000;">, </span><span sty=
le=3D"color: #0000ff;">float</span><span style=3D"color: #000000;">, </span=
><span style=3D"color: #0000ff;">bool</span><span style=3D"color: #000000;"=
>, </span><span style=3D"color: #0000ff;">char</span><span style=3D"color: =
#000000;">&gt;, </span><span style=3D"color: #0000ff;">char</span><span sty=
le=3D"color: #000000;">&gt;());</span></div><div><span style=3D"color: #000=
000;"><br></span></div><div><span style=3D"color: #000000;"><br></span></di=
v></div></div><div>Regards,</div><div>Maciej<br></div><div><br></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/b5eb854b-3ddd-4173-b71e-f6ce85fd887c%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/b5eb854b-3ddd-4173-b71e-f6ce85fd887c=
%40isocpp.org</a>.<br />

------=_Part_2311_638433238.1543394214966--

------=_Part_2310_921556040.1543394214966--

.


Author: Brian Bi <bbi5291@gmail.com>
Date: Fri, 30 Nov 2018 13:16:57 -0600
Raw View
--0000000000004f3922057be6a548
Content-Type: text/plain; charset="UTF-8"

I think the standard text could benefit from being a lot more clear about
(1) function template parameter packs that don't occur at the end of the
parameter-type-list, and (2) template parameter packs that don't occur at
the end of the template parameter list, in cases where some template
arguments are explicitly specified. That being said:

Based on CWG 2105
<http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2105>, it
appears that the committee has affirmed the following interpretation: when
you explicitly specify template arguments, any template parameter pack is
considered to consume all of the remaining arguments (i.e., ones not
consumed by previous non-pack template parameters). The value specified for
the template parameter pack is then substituted into the function type and
deduction continues. Thus, the compiler should be able to go on to deduce
Head and Tail.

It appears that trunk GCC gives a nonsensical error message, which makes me
think that it has a bug, not that the developers intended to reject your
code.

prog.cc:9:36: error: expansion pattern 'long unsigned int' contains no
parameter packs
    9 | -> decltype(nthImpl3<decltype(Ints)...>(ts...));
      |                                    ^~~



On Wed, Nov 28, 2018 at 2:36 AM <m.cencora@gmail.com> wrote:

> Hi,
>
> is following code correct according to standard?
> In other words do compilers correctly deduce Ts... parameter pack in
> nthImpl3 as decltype(Ints)... as invoked in nthImpl2?
>
> It seems to work with clang, and all but trunk gcc versions.
>
> #include <type_traits>
> #include <utility>
>
> template <typename ...Ts, typename Head, typename ...Tail>
> Head nthImpl3(Ts..., Head head, Tail ...);
>
> template <std::size_t ...Ints, typename ...Ts>
> auto nthimpl2(std::index_sequence<Ints...>, Ts ...ts)
> -> decltype(nthImpl3<decltype(Ints)...>(ts...));
>
>
> template <int N, typename ...Ts>
> struct nth_impl
> {
> using type = decltype(nthimpl2(std::make_index_sequence<N>(), Ts{}...));
> };
>
> template <int N, typename ...Ts>
> using nth_type = typename nth_impl<N, Ts...>::type;
>
>
> static_assert(std::is_same<nth_type<0, float, bool, char>, float>());
> static_assert(std::is_same<nth_type<1, float, bool, char>, bool>());
> static_assert(std::is_same<nth_type<2, float, bool, char>, char>());
>
>
> Regards,
> Maciej
>
> --
> 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/b5eb854b-3ddd-4173-b71e-f6ce85fd887c%40isocpp.org
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/b5eb854b-3ddd-4173-b71e-f6ce85fd887c%40isocpp.org?utm_medium=email&utm_source=footer>
> .
>


--
*Brian Bi*

--
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/CAMmfjbMch2PKmFpEVG5DYha%2B868jgKxuQLYk44OZrFZDmOQR_g%40mail.gmail.com.

--0000000000004f3922057be6a548
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div>I think the standard text could benefit from being a =
lot more clear about (1) function template parameter packs that don&#39;t o=
ccur at the end of the parameter-type-list, and (2) template parameter pack=
s that don&#39;t occur at the end of the template parameter list, in cases =
where some template arguments are explicitly specified. That being said:</d=
iv><div><br></div><div>Based on=C2=A0<a href=3D"http://www.open-std.org/jtc=
1/sc22/wg21/docs/cwg_active.html#2105" target=3D"_blank">CWG 2105</a>, it a=
ppears that the committee has affirmed the following interpretation: when y=
ou explicitly specify template arguments, any template parameter pack is co=
nsidered to consume all of the remaining arguments (i.e., ones not consumed=
 by previous non-pack template parameters). The value specified for the tem=
plate parameter pack is then substituted into the function type and deducti=
on continues. Thus, the compiler should be able to go on to deduce Head and=
 Tail.</div><div><br></div><div>It appears that trunk GCC gives a nonsensic=
al error message, which makes me think that it has a bug, not that the deve=
lopers intended to reject your code.</div><div><br></div><div><pre class=3D=
"gmail-CompilerMessageE" style=3D"box-sizing:border-box;overflow:auto;font-=
family:&quot;Courier New&quot;,monospace;font-size:13px;padding:0px;margin-=
top:0px;margin-bottom:10px;line-height:1.42857;color:rgb(255,0,0);word-brea=
k:break-all;background-color:rgb(0,0,0);border:0px;border-radius:4px;white-=
space:pre-wrap">prog.cc:9:36: error: expansion pattern &#39;long unsigned i=
nt&#39; contains no parameter packs
    9 | -&gt; decltype(nthImpl3&lt;decltype(Ints)...&gt;(ts...));
      |                                    ^~~</pre></div><div><br></div></=
div><br><div class=3D"gmail_quote"><div dir=3D"ltr">On Wed, Nov 28, 2018 at=
 2:36 AM &lt;<a href=3D"mailto:m.cencora@gmail.com" target=3D"_blank">m.cen=
cora@gmail.com</a>&gt; wrote:<br></div><blockquote class=3D"gmail_quote" st=
yle=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div =
dir=3D"ltr"><div>Hi,</div><div><br></div><div>is following code correct acc=
ording to standard?</div><div>In other words do compilers correctly deduce =
Ts... parameter pack in nthImpl3 as decltype(Ints)... as invoked in nthImpl=
2?</div><div><br></div><div>It seems to work with clang, and all but trunk =
gcc versions.</div><div><br></div><div><div><div><span style=3D"color:#0000=
ff">#include</span><span style=3D"color:#000000"> &lt;type_traits&gt;</span=
></div><div><span style=3D"color:#0000ff">#include</span><span style=3D"col=
or:#000000"> &lt;utility&gt;</span></div><br><div><span style=3D"color:#000=
0ff">template</span><span style=3D"color:#000000"> &lt;</span><span style=
=3D"color:#0000ff">typename</span><span style=3D"color:#000000"> ...Ts, </s=
pan><span style=3D"color:#0000ff">typename</span><span style=3D"color:#0000=
00"> Head, </span><span style=3D"color:#0000ff">typename</span><span style=
=3D"color:#000000"> ...Tail&gt;</span></div><div><span style=3D"color:#0000=
00">Head nthImpl3(Ts..., Head head, Tail ...);</span></div><br><div><span s=
tyle=3D"color:#0000ff">template</span><span style=3D"color:#000000"> &lt;st=
d::size_t ...Ints, </span><span style=3D"color:#0000ff">typename</span><spa=
n style=3D"color:#000000"> ...Ts&gt;</span></div><div><span style=3D"color:=
#0000ff">auto</span><span style=3D"color:#000000"> nthimpl2(std::index_sequ=
ence&lt;Ints...&gt;, Ts ...ts) </span></div><div><span style=3D"color:#0000=
00">    -&gt; </span><span style=3D"color:#0000ff">decltype</span><span sty=
le=3D"color:#000000">(nthImpl3&lt;</span><span style=3D"color:#0000ff">decl=
type</span><span style=3D"color:#000000">(Ints)...&gt;(ts...));</span></div=
><br><br><div><span style=3D"color:#0000ff">template</span><span style=3D"c=
olor:#000000"> &lt;</span><span style=3D"color:#0000ff">int</span><span sty=
le=3D"color:#000000"> N, </span><span style=3D"color:#0000ff">typename</spa=
n><span style=3D"color:#000000"> ...Ts&gt;</span></div><div><span style=3D"=
color:#0000ff">struct</span><span style=3D"color:#000000"> nth_impl</span><=
/div><div><span style=3D"color:#000000">{</span></div><div><span style=3D"c=
olor:#000000">    </span><span style=3D"color:#0000ff">using</span><span st=
yle=3D"color:#000000"> type =3D </span><span style=3D"color:#0000ff">declty=
pe</span><span style=3D"color:#000000">(nthimpl2(std::make_index_sequence&l=
t;N&gt;(), Ts{}...));</span></div><div><span style=3D"color:#000000">};</sp=
an></div><br><div><span style=3D"color:#0000ff">template</span><span style=
=3D"color:#000000"> &lt;</span><span style=3D"color:#0000ff">int</span><spa=
n style=3D"color:#000000"> N, </span><span style=3D"color:#0000ff">typename=
</span><span style=3D"color:#000000"> ...Ts&gt;</span></div><div><span styl=
e=3D"color:#0000ff">using</span><span style=3D"color:#000000"> nth_type =3D=
 </span><span style=3D"color:#0000ff">typename</span><span style=3D"color:#=
000000"> nth_impl&lt;N, Ts...&gt;::type;</span></div><br><br><div><span sty=
le=3D"color:#0000ff">static_assert</span><span style=3D"color:#000000">(std=
::is_same&lt;nth_type&lt;</span><span style=3D"color:#09885a">0</span><span=
 style=3D"color:#000000">, </span><span style=3D"color:#0000ff">float</span=
><span style=3D"color:#000000">, </span><span style=3D"color:#0000ff">bool<=
/span><span style=3D"color:#000000">, </span><span style=3D"color:#0000ff">=
char</span><span style=3D"color:#000000">&gt;, </span><span style=3D"color:=
#0000ff">float</span><span style=3D"color:#000000">&gt;());</span></div><di=
v><span style=3D"color:#0000ff">static_assert</span><span style=3D"color:#0=
00000">(std::is_same&lt;nth_type&lt;</span><span style=3D"color:#09885a">1<=
/span><span style=3D"color:#000000">, </span><span style=3D"color:#0000ff">=
float</span><span style=3D"color:#000000">, </span><span style=3D"color:#00=
00ff">bool</span><span style=3D"color:#000000">, </span><span style=3D"colo=
r:#0000ff">char</span><span style=3D"color:#000000">&gt;, </span><span styl=
e=3D"color:#0000ff">bool</span><span style=3D"color:#000000">&gt;());</span=
></div><div><span style=3D"color:#0000ff">static_assert</span><span style=
=3D"color:#000000">(std::is_same&lt;nth_type&lt;</span><span style=3D"color=
:#09885a">2</span><span style=3D"color:#000000">, </span><span style=3D"col=
or:#0000ff">float</span><span style=3D"color:#000000">, </span><span style=
=3D"color:#0000ff">bool</span><span style=3D"color:#000000">, </span><span =
style=3D"color:#0000ff">char</span><span style=3D"color:#000000">&gt;, </sp=
an><span style=3D"color:#0000ff">char</span><span style=3D"color:#000000">&=
gt;());</span></div><div><span style=3D"color:#000000"><br></span></div><di=
v><span style=3D"color:#000000"><br></span></div></div></div><div>Regards,<=
/div><div>Maciej<br></div><div><br></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" target=3D"_=
blank">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">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/b5eb854b-3ddd-4173-b71e-f6ce85fd887c%=
40isocpp.org?utm_medium=3Demail&amp;utm_source=3Dfooter" target=3D"_blank">=
https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/b5eb854b-3ddd-=
4173-b71e-f6ce85fd887c%40isocpp.org</a>.<br>
</blockquote></div><br clear=3D"all"><div><br></div>-- <br><div dir=3D"ltr"=
 class=3D"m_2258975033737418938gmail_signature" data-smartmail=3D"gmail_sig=
nature"><div dir=3D"ltr"><div><div dir=3D"ltr"><font color=3D"#c0c0c0"><i>B=
rian Bi</i></font><br><div></div><div></div><div></div></div></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/CAMmfjbMch2PKmFpEVG5DYha%2B868jgKxuQL=
Yk44OZrFZDmOQR_g%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">h=
ttps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAMmfjbMch2PKmF=
pEVG5DYha%2B868jgKxuQLYk44OZrFZDmOQR_g%40mail.gmail.com</a>.<br />

--0000000000004f3922057be6a548--

.