Topic: N4320: interaction with template type deduction


Author: David Krauss <potswa@mac.com>
Date: Fri, 08 May 2015 17:21:20 +0800
Raw View
--Apple-Mail=_BE661374-7C52-43AD-BDBD-F009053FF360
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8

Hi Jens,

Thanks for fixing CWG DR 92! I addressed a similar problem recently, and so=
me desirable template deduction cases might be missing from N4320.

How can a template inspect whether a function is noexcept or not? Perhaps m=
ore importantly, how can it avoid such a dependency?

Ideally, this template will accept pointer to noexcept function types:

template< typename fptr >
struct decompose_fptr;

template< typename ret, typename ... arg >
struct decompose_fptr< ret (*)( arg ... ) > {
    typedef ret return_type;
    typedef std::tuple< arg ... > arg_types;
};

And this will extract the exception-specification from a function pointer t=
ype:

template< typename fptr >
bool decompose_fptr;

template< typename ret, typename ... arg, bool exc >
constexpr bool decompose_fptr< ret (*)( arg ... ) noexcept( exc ) > =3D exc=
;

Here=E2=80=99s an outline of my proposed solution, from a draft revision <h=
ttp://bit.ly/genlife> to N4221. (N4221 was rejected, but all the complaints=
 resulted from my specifier being not part of the type system, but based on=
 exception-specification semantics.) It=E2=80=99s not standardese, but to a=
pply it to exceptions, just replace =E2=80=9Clifetime qualifier=E2=80=9D wi=
th =E2=80=9Cnoexcept specifier.=E2=80=9D
> In decompositional deduction of a function type ([temp.deduct.type] =C2=
=A714.8.2.5), the constant expression in a lifetime qualifier is a deduced =
context from which a Boolean template parameter may be initialized. If the =
parameter declaration does not mention any lifetime specifier, or if the de=
duction is from a conversion operation ([temp.deduct.funcaddr] =C2=A714.8.2=
..6), then a specifier export(B) is introduced with an anonymous bool templa=
te parameter B. (In all other aspects, the absence of a lifetime specifier =
is the same as export(false), so they do not represent distinct types.) Thu=
s, traditional decomposition works but it loses information. =E2=80=A6 In d=
eduction from conversion, the introduced anonymous parameter may replace a =
declared parameter which otherwise would have been deduced. The declared pa=
rameter is used again once deduction succeeds, it is not initialized by the=
 anonymous parameter, and deduction fails if its value has not been determi=
ned otherwise. For an explicit cast, any deduced qualifications are then re=
placed by converting the result to the given signature. Otherwise, the qual=
ifications must be an exact match or implicitly convertible.=20
>=20
The latter bit of trickiness is intended to solve some corner cases:
1. Allow function template declaration matching to work when the specifier =
is omitted from the redeclaration.
2. Avoid allowing cast expression to determine the specifier of a function =
template specialization, i.e. letting a function lazily ask its user whethe=
r or not it is noexcept.

Coincidentally, just today I=E2=80=99ve set about implementing this beast, =
in Clang. Hopefully when I get around to the template aspects I can take ca=
re of exception specifications too.

--=20

---=20
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 e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

--Apple-Mail=_BE661374-7C52-43AD-BDBD-F009053FF360
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=UTF-8

<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dutf-8"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-mode: s=
pace; -webkit-line-break: after-white-space;" class=3D"">Hi Jens,<div class=
=3D""><br class=3D""></div><div class=3D"">Thanks for fixing CWG DR 92! I a=
ddressed a similar problem recently, and some desirable template deduction =
cases might be missing from N4320.</div><div class=3D""><br class=3D""></di=
v><div class=3D"">How can a template inspect whether a function is <font fa=
ce=3D"Courier" class=3D"">noexcept</font> or not? Perhaps more importantly,=
 how can it avoid such a dependency?</div><div class=3D""><br class=3D""></=
div><div class=3D"">Ideally, this template will accept pointer to noexcept =
function types:</div><div class=3D""><br class=3D""></div><div class=3D""><=
font face=3D"Courier" class=3D"">template&lt; typename fptr &gt;</font></di=
v><div class=3D""><font face=3D"Courier" class=3D"">struct decompose_fptr;<=
/font></div><div class=3D""><font face=3D"Courier" class=3D""><br class=3D"=
"></font></div><div class=3D""><font face=3D"Courier" class=3D"">template&l=
t; typename ret, typename ... arg &gt;</font></div><div class=3D""><font fa=
ce=3D"Courier" class=3D"">struct decompose_fptr&lt; ret (*)( arg ... ) &gt;=
 {</font></div><div class=3D""><font face=3D"Courier" class=3D"">&nbsp; &nb=
sp; typedef ret return_type;</font></div><div class=3D""><font face=3D"Cour=
ier" class=3D"">&nbsp; &nbsp; typedef std::tuple&lt; arg ... &gt; arg_types=
;</font></div><div class=3D""><font face=3D"Courier" class=3D"">};</font></=
div><div class=3D""><br class=3D""></div><div class=3D"">And this will extr=
act the exception-specification from a function pointer type:</div><div cla=
ss=3D""><br class=3D""></div><div class=3D""><div class=3D""><font face=3D"=
Courier" class=3D"">template&lt; typename fptr &gt;</font></div><div class=
=3D""><font face=3D"Courier" class=3D"">bool decompose_fptr;</font></div></=
div><div class=3D""><font face=3D"Courier" class=3D""><br class=3D""></font=
></div><div class=3D""><span style=3D"font-family: Courier;" class=3D"">tem=
plate&lt;&nbsp;</span><span style=3D"font-family: Courier;" class=3D"">type=
name ret, typename ... arg, bool exc</span><span style=3D"font-family: Cour=
ier;" class=3D"">&nbsp;&gt;</span></div><div class=3D""><div class=3D""><fo=
nt face=3D"Courier" class=3D"">constexpr bool decompose_fptr&lt; ret (*)( a=
rg ... ) noexcept( exc ) &gt; =3D exc;</font></div></div><div class=3D""><b=
r class=3D""></div><div class=3D"">Here=E2=80=99s an outline of my proposed=
 solution, from a&nbsp;<a href=3D"http://bit.ly/genlife" class=3D"">draft r=
evision</a>&nbsp;to N4221. (N4221 was rejected, but all the complaints resu=
lted from my specifier being not part of the type system, but based on exce=
ption-specification semantics.) It=E2=80=99s not standardese, but to apply =
it to exceptions, just replace =E2=80=9Clifetime qualifier=E2=80=9D with =
=E2=80=9Cnoexcept specifier.=E2=80=9D</div><div class=3D""><blockquote type=
=3D"cite" class=3D""><div class=3D"page" title=3D"Page 9"><div class=3D"sec=
tion" style=3D"background-color: rgb(100.000000%, 100.000000%, 100.000000%)=
"><div class=3D"layoutArea"><div class=3D"column"><p class=3D"">In decompos=
itional deduction of a function type ([temp.deduct.type] =C2=A714.8.2.5), t=
he constant
expression in a lifetime qualifier is a deduced context from which a Boolea=
n template parameter
may be initialized. If the parameter declaration does not mention any lifet=
ime specifier, or if the
deduction is from a conversion operation ([temp.deduct.funcaddr] =C2=A714.8=
..2.6), then a specifier
<span style=3D"font-family: Courier;" class=3D"">export(</span><span style=
=3D"font-family: Courier; font-style: oblique;" class=3D"">B</span><span st=
yle=3D"font-family: Courier;" class=3D"">) </span>is introduced with an ano=
nymous <span style=3D"font-family: Courier;" class=3D"">bool </span>templat=
e parameter <span style=3D"font-family: Courier; font-style: oblique;" clas=
s=3D"">B</span>. (In all other aspects,
the absence of a lifetime specifier is the same as <span style=3D"font-fami=
ly: Courier;" class=3D"">export(false)</span>, so they do not represent
distinct types.) Thus, traditional decomposition works but it loses informa=
tion. =E2=80=A6 In deduction from conversion, the introduced anonymous
parameter may replace a declared parameter which otherwise would have been =
deduced. The
declared parameter is used again once deduction succeeds, it is not initial=
ized by the anonymous
parameter, and deduction fails if its value has not been determined otherwi=
se. For an explicit
cast, any deduced qualifications are then replaced by converting the result=
 to the given signature.
Otherwise, the qualifications must be an exact match or implicitly converti=
ble.&nbsp;</p></div></div></div></div></blockquote><div class=3D"">The latt=
er bit of trickiness is intended to solve some corner cases:</div><div clas=
s=3D"">1. Allow function template declaration matching to work when the spe=
cifier is omitted from the redeclaration.</div><div class=3D"">2. Avoid all=
owing cast expression to determine the specifier of a function template spe=
cialization, i.e. letting a function lazily ask its user whether or not it =
is noexcept.</div><div class=3D""><br class=3D""></div><div class=3D"">Coin=
cidentally, just today I=E2=80=99ve set about implementing this beast, in C=
lang. Hopefully when I get around to the template aspects I can take care o=
f exception specifications too.</div><div class=3D""><blockquote type=3D"ci=
te" class=3D""><div class=3D"page" title=3D"Page 9"><div class=3D"section" =
style=3D"background-color: rgb(255, 255, 255);"><div class=3D"layoutArea"><=
div class=3D"column"></div></div></div></div></blockquote></div></div></bod=
y></html>

<p></p>

-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--Apple-Mail=_BE661374-7C52-43AD-BDBD-F009053FF360--

.


Author: Jens Maurer <Jens.Maurer@gmx.net>
Date: Sat, 09 May 2015 06:16:27 +0200
Raw View
On 05/08/2015 11:21 AM, David Krauss wrote:
> Hi Jens,
>
> Thanks for fixing CWG DR 92! I addressed a similar problem recently, and some desirable template deduction cases might be missing from N4320.
>
> How can a template inspect whether a function is noexcept or not? Perhaps more importantly, how can it avoid such a dependency?
>
> Ideally, this template will accept pointer to noexcept function types:

In a function call context, it would, because of automatic conversion.
In a specialization context, we need an exact type match, and you don't
have that here.

> And this will extract the exception-specification from a function pointer type:

That is not going to work.

> template< typename ret, typename ... arg, bool exc >
> constexpr bool decompose_fptr< ret (*)( arg ... ) noexcept( exc ) > = exc;

Jens

--

---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

.


Author: David Krauss <potswa@mac.com>
Date: Sat, 09 May 2015 14:07:22 +0800
Raw View
--Apple-Mail=_2986371B-A969-4122-911B-4928B5334B95
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8


> On 2015=E2=80=9305=E2=80=9309, at 12:16 PM, Jens Maurer <Jens.Maurer@gmx.=
net> wrote:
>=20
> In a specialization context, we need an exact type match, and you don't
> have that here.

Requiring an exact match is the problem (breaking change) that I am address=
ing.

> In a function call context, it would, because of automatic conversion.

That conversion loses information. Why not avoid it? Preserving the excepti=
on-specification can be done automatically. Doing it manually according to =
N4320 requires multiple overloads.

Function templates seldom inspect signatures like that, so it=E2=80=99s som=
ewhat a corner case.

> That is not going to work.

That=E2=80=99s begging the question, should it work?

noexcept(true) is already an alternate spelling of noexcept and noexcept(fa=
lse) an alternate spelling of no exception-specification. It=E2=80=99s easi=
er to deal with one bool variable than two overloads or partial specializat=
ions. And consider that with the breaking change, users will be required to=
 account for the difference.

Also, for member function types, it=E2=80=99s not just two overloads or par=
tial specializations, because every part of the signature requires an exact=
 match at the same time. 4 cv-qualifications x 3 ref-qualifiers x 2 possibi=
lities for the va_args ellipsis x 2 noexcept-specifications =3D 48 cases.

--=20

---=20
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 e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

--Apple-Mail=_2986371B-A969-4122-911B-4928B5334B95
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=UTF-8

<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dutf-8"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-mode: s=
pace; -webkit-line-break: after-white-space;" class=3D""><br class=3D""><di=
v><blockquote type=3D"cite" class=3D""><div class=3D"">On 2015=E2=80=9305=
=E2=80=9309, at 12:16 PM, Jens Maurer &lt;<a href=3D"mailto:Jens.Maurer@gmx=
..net" class=3D"">Jens.Maurer@gmx.net</a>&gt; wrote:</div></blockquote><bloc=
kquote type=3D"cite" class=3D""><br class=3D""></blockquote><blockquote typ=
e=3D"cite" class=3D""><div class=3D"">In a specialization context, we need =
an exact type match, and you don't<br class=3D"">have that here.<br class=
=3D""></div></blockquote><div><br class=3D""></div><div><div>Requiring an e=
xact match is the problem (breaking change) that I am addressing.</div><div=
><br class=3D""></div><div><blockquote type=3D"cite" class=3D"">In a functi=
on call context, it would, because of automatic conversion.<br class=3D""><=
/blockquote><div><br class=3D""></div><div>That conversion loses informatio=
n. Why not avoid it? Preserving the exception-specification can be done aut=
omatically. Doing it manually according to N4320 requires multiple overload=
s.</div><div><br class=3D""></div><div>Function templates seldom inspect si=
gnatures like that, so it=E2=80=99s somewhat a corner case.</div><div class=
=3D""><br class=3D""></div></div><blockquote type=3D"cite" class=3D"">That =
is not going to work.<br class=3D""></blockquote><div><br class=3D""></div>=
<div>That=E2=80=99s begging the question,&nbsp;<i class=3D"">should</i>&nbs=
p;it work?</div><div><font face=3D"Courier" class=3D""><br class=3D""></fon=
t></div><div><font face=3D"Courier" class=3D"">noexcept(true)</font>&nbsp;i=
s already an alternate spelling of <font face=3D"Courier" class=3D"">noexce=
pt</font> and&nbsp;<font face=3D"Courier" class=3D"">noexcept(false)</font>=
&nbsp;an alternate spelling of no exception-specification. It=E2=80=99s eas=
ier to deal with one <font face=3D"Courier" class=3D"">bool</font> variable=
 than two overloads or partial specializations. And consider that with the =
breaking change, users will be required to account for the difference.</div=
><div><br class=3D""></div><div>Also, for member function types, it=E2=80=
=99s not just two overloads or partial specializations, because every part =
of the signature requires an exact match at the same time. 4 cv-qualificati=
ons x 3 ref-qualifiers x 2 possibilities for the va_args ellipsis x 2 noexc=
ept-specifications =3D 48 cases.</div></div></div></body></html>

<p></p>

-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--Apple-Mail=_2986371B-A969-4122-911B-4928B5334B95--

.


Author: Jens Maurer <Jens.Maurer@gmx.net>
Date: Sat, 09 May 2015 15:09:38 +0200
Raw View
On 05/09/2015 08:07 AM, David Krauss wrote:
>=20
>> On 2015=E2=80=9305=E2=80=9309, at 12:16 PM, Jens Maurer <Jens.Maurer@gmx=
..net <mailto:Jens.Maurer@gmx.net>> wrote:
>>
>> In a specialization context, we need an exact type match, and you don't
>> have that here.
>=20
> Requiring an exact match is the problem (breaking change) that I am addre=
ssing.
>=20
>> In a function call context, it would, because of automatic conversion.
>=20
> That conversion loses information. Why not avoid it? Preserving the excep=
tion-specification can be done automatically. Doing it manually according t=
o N4320 requires multiple overloads.

Well, you shouldn't be able to pass a non-noexcept function to f, right?

  void f( void(*)(int) noexcept );

Whereas passing a noexcept function to g is just fine:

  void g( void(*)(int) );


>> That is not going to work.
>=20
> That=E2=80=99s begging the question, /should/ it work?
>=20
> noexcept(true) is already an alternate spelling of noexcept and noexcept(=
false) an alternate spelling of no exception-specification. It=E2=80=99s ea=
sier to deal with one bool variable than two overloads or partial specializ=
ations. And consider that with the breaking change, users will be required =
to account for the difference.
>=20
> Also, for member function types, it=E2=80=99s not just two overloads or p=
artial specializations, because every part of the signature requires an exa=
ct match at the same time. 4 cv-qualifications x 3 ref-qualifiers x 2 possi=
bilities for the va_args ellipsis x 2 noexcept-specifications =3D 48 cases.

Yes.  It seems to me if we want to do something here, it should be
some generic "function decorator" matching in template type deduction,
not specific to noexcept.

Jens

--=20

---=20
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 e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

.


Author: David Krauss <potswa@mac.com>
Date: Sun, 10 May 2015 00:04:48 +0800
Raw View
--Apple-Mail=_C4DA3D56-DCBE-4DD3-965B-8E436A13F6DA
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8


> On 2015=E2=80=9305=E2=80=9309, at 9:09 PM, Jens Maurer <Jens.Maurer@gmx.n=
et> wrote:
>=20
> Well, you shouldn't be able to pass a non-noexcept function to f, right?

I never suggested otherwise.

> Yes.  It seems to me if we want to do something here, it should be
> some generic "function decorator" matching in template type deduction,
> not specific to noexcept.

Some syntax would need to be invented, which already exists for exception-s=
pecifications.

Anyway, I=E2=80=99m just sharing the solution from my proposal and letting =
you know my implementation plans.

Although it=E2=80=99s only nice-to-have for exception-specifications, it=E2=
=80=99s necessary for my proposal because the implicit conversion goes the =
other way =E2=80=94 like const, the qualifier can be implicitly added but n=
ot ignored.

--=20

---=20
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 e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

--Apple-Mail=_C4DA3D56-DCBE-4DD3-965B-8E436A13F6DA
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=UTF-8

<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dutf-8"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-mode: s=
pace; -webkit-line-break: after-white-space;" class=3D""><br class=3D""><di=
v><blockquote type=3D"cite" class=3D""><div class=3D"">On 2015=E2=80=9305=
=E2=80=9309, at 9:09 PM, Jens Maurer &lt;<a href=3D"mailto:Jens.Maurer@gmx.=
net" class=3D"">Jens.Maurer@gmx.net</a>&gt; wrote:</div><br class=3D"Apple-=
interchange-newline"><div class=3D"">Well, you shouldn't be able to pass a =
non-noexcept function to f, right?<br class=3D""></div></blockquote><div><b=
r class=3D""></div><div>I never suggested otherwise.</div><br class=3D""><b=
lockquote type=3D"cite" class=3D""><div class=3D"">Yes. &nbsp;It seems to m=
e if we want to do something here, it should be<br class=3D"">some generic =
"function decorator" matching in template type deduction,<br class=3D"">not=
 specific to noexcept.<br class=3D""></div></blockquote></div><br class=3D"=
"><div class=3D"">Some syntax would need to be invented, which already exis=
ts for exception-specifications.</div><div class=3D""><br class=3D""></div>=
<div class=3D"">Anyway, I=E2=80=99m just sharing the solution from my propo=
sal and letting you know my implementation plans.</div><div class=3D""><br =
class=3D""></div><div class=3D"">Although it=E2=80=99s only nice-to-have fo=
r exception-specifications, it=E2=80=99s necessary for my proposal because =
the implicit conversion goes the other way =E2=80=94 like <font face=3D"Cou=
rier" class=3D"">const</font>, the qualifier can be implicitly added but no=
t ignored.</div></body></html>

<p></p>

-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--Apple-Mail=_C4DA3D56-DCBE-4DD3-965B-8E436A13F6DA--

.