Topic: Conditional explicit specification - explicit(constant-expression)


Author: Tomasz <tomaszkam@gmail.com>
Date: Fri, 24 Apr 2015 09:18:20 -0700 (PDT)
Raw View
------=_Part_601_1570827894.1429892300251
Content-Type: multipart/alternative;
 boundary="----=_Part_602_1568410384.1429892300256"

------=_Part_602_1568410384.1429892300256
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

I would like to present you and idea to provide a second conditional=20
explicit specifier in the form explicit(constant-expression), that work=20
work in the similar manner like noexcept specifier.=20

I came up with this idea while reading the N4387: Improving pair and tuple,=
=20
revision 3=20
<http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2015/n4387.html> paper.=
=20
This paper proposes that the pair<T,U> to be implicitly constructible from=
=20
the expression {e1, e2} if T is implicitly construtible from e1 and U from=
=20
T2. That means that pair<int,double> may be initialized with {1, 2.0},=20
while the same expression will not be accepted for=20
pair<std::chrono::second, std::chrono::minutes>. The solution presented in=
=20
the paper is based on providing the two overloads that differs only in the=
=20
cosntrain and presence of the explicit specifier (bodies are the same)

template<typename T1, typename T2>
  template<typename U1, typename U2
           typename =3D std::enable_if_t<
             is_construtible<T1, U1&&>{} && is_construtible<T2, U2&&>{} &&
             is_convertible<U1&&, T1>{} && is_convertible<U2&&, T2>{}
           >>         =20
pair<T1, T2>::pair(U1&& u1, U2&& u2);

template<typename T1, typename T2>
  template<typename U1, typename U2
           typename =3D std::enable_if_t<
             is_construtible<T1, U1&&>{} && is_construtible<T2, U2&&>{} &&
             !(is_convertible<U1&&, T1>{} && is_convertible<U2&&, T2>{})
          >>         =20
explicit pair<T1, T2>::pair(U1&& u1, U2&& u2);

With addition of conditional noexcept, this may be reduced to one overload:
template<typename T1, typename T2>
  template<typename U1, typename U2
           typename =3D std::enable_if_t<
                          is_construtible<T1, U1&&>{} &&=20
is_construtible<T2, U2&&>{}
          >>
explicit(!(is_convertible<U1&&, T1>{} && is_convertible<U2&&, T2>{}))=20
  pair<T1, T2>::pair(U1&& u1, U2&& u2);

It will also address not such easy to implement case of constructor taking=
=20
T1 and T2 types explicitly, that is discussed in Implementation Hint=20
section of the paper.


*It is change usable for cases on the other classes?*Yes, I consider it=20
usable for any type wrapper object that exposes converting constructor.


*Is this change backward compatible?*Yes it adds totally new version of=20
explicit specifier. The no-argument version may be threated as=20
explicit(true), effectively reproducing design of noexcept. Although the=20
parallelism between proposed version of explicit and noexcept stops here -=
=20
I do not propose to add explicit operator.


*It is blocking implementation of the N4387?*No, the paper does no require=
=20
any certain implementation. Provision of the conditional explicit will open=
=20
the way to simpler, non-repeatable implementation. It will also simplify=20
the wording.


*Does the reduction of writing worth language change?*I think yes. You may=
=20
notice that the mentioned paper uses some form of conditional explicit=20
specifier (EXPLICIT) to avoid repeating the specification. If we think that=
=20
is is worth to add conditional explicit to simplify specification, I think=
=20
that is also worth to have one for code.

Tomasz Kami=C5=84ski

--=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/.

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

<div dir=3D"ltr">I would like to present you and idea to provide a second c=
onditional explicit specifier in the form explicit(constant-expression), th=
at work work in the similar manner like noexcept specifier. <br><br>I came =
up with this idea while reading the <a href=3D"http://www.open-std.org/JTC1=
/SC22/WG21/docs/papers/2015/n4387.html">N4387: Improving pair and tuple, re=
vision 3</a> paper. This paper proposes that the pair&lt;T,U&gt; to be impl=
icitly constructible from the expression {e1, e2} if T is implicitly constr=
utible from e1 and U from T2. That means that pair&lt;int,double&gt; may be=
 initialized with {1, 2.0}, while the same expression will not be accepted =
for pair&lt;std::chrono::second, std::chrono::minutes&gt;. The solution pre=
sented in the paper is based on providing the two overloads that differs on=
ly in the cosntrain and presence of the explicit specifier (bodies are the =
same)<br><br><span style=3D"font-family: courier new,monospace;">template&l=
t;typename T1, typename T2&gt;<br>&nbsp; template&lt;typename U1, typename =
U2<br>&nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; typename =3D std::enable_if_=
t&lt;<br>&nbsp;&nbsp; &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; is_=
construtible&lt;T1, U1&amp;&amp;&gt;{} &amp;&amp; is_construtible&lt;T2, U2=
&amp;&amp;&gt;{} &amp;&amp;<br>&nbsp;&nbsp;&nbsp; &nbsp; &nbsp;&nbsp;&nbsp;=
&nbsp;&nbsp;&nbsp; is_convertible&lt;U1&amp;&amp;, T1&gt;{} &amp;&amp; is_c=
onvertible&lt;U2&amp;&amp;, T2&gt;{}<br>&nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &=
nbsp; &gt;&gt;&nbsp; &nbsp; &nbsp;&nbsp; &nbsp;&nbsp; <br>pair&lt;T1, T2&gt=
;::pair(U1&amp;&amp; u1, U2&amp;&amp; u2);<br><br>template&lt;typename T1, =
typename T2&gt;<br>&nbsp; template&lt;typename U1, typename U2<br>&nbsp; &n=
bsp;&nbsp; &nbsp; &nbsp; &nbsp; typename =3D std::enable_if_t&lt;<br>&nbsp;=
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; is_const=
rutible&lt;T1, U1&amp;&amp;&gt;{} &amp;&amp; is_construtible&lt;T2, U2&amp;=
&amp;&gt;{} &amp;&amp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&=
nbsp;&nbsp;&nbsp;&nbsp; !(is_convertible&lt;U1&amp;&amp;, T1&gt;{} &amp;&am=
p; is_convertible&lt;U2&amp;&amp;, T2&gt;{})<br>&nbsp; &nbsp; &nbsp; &nbsp;=
 &nbsp; &gt;&gt;&nbsp; &nbsp; &nbsp;&nbsp; &nbsp;&nbsp; <br>explicit pair&l=
t;T1, T2&gt;::pair(U1&amp;&amp; u1, U2&amp;&amp; u2);</span><br><br>With ad=
dition of conditional noexcept, this may be reduced to one overload:<br><sp=
an style=3D"font-family: courier new,monospace;">template&lt;typename T1, t=
ypename T2&gt;<br>&nbsp; template&lt;typename U1, typename U2<br>&nbsp; &nb=
sp;&nbsp; &nbsp; &nbsp; &nbsp; typename =3D std::enable_if_t&lt;</span><br>=
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
 <span style=3D"font-family: courier new,monospace;">is_construtible&lt;T1,=
 U1&amp;&amp;&gt;{} &amp;&amp; is_construtible&lt;T2, U2&amp;&amp;&gt;{}<br=
>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &gt;&gt;<br>explici=
t(!(</span><span style=3D"font-family: courier new,monospace;">is_convertib=
le&lt;U1&amp;&amp;, T1&gt;{} &amp;&amp; is_convertible&lt;U2&amp;&amp;, T2&=
gt;{})) <br>&nbsp; </span><span style=3D"font-family: courier new,monospace=
;">pair&lt;T1, T2&gt;::pair(U1&amp;&amp; u1, U2&amp;&amp; u2);<br><br><span=
 style=3D"font-family: arial,sans-serif;">It will also address not such eas=
y to implement case of constructor taking T1 and T2 types explicitly, that =
is discussed in Implementation Hint section of the paper.<br><b><br>It is c=
hange usable for cases on the other classes?<br></b>Yes, I consider it usab=
le for any type wrapper object that exposes converting constructor.<br><br>=
<b>Is this change backward compatible?<br></b>Yes it adds totally new versi=
on of explicit specifier. The no-argument version may be threated as explic=
it(true), effectively reproducing design of noexcept. Although the parallel=
ism between proposed version of explicit and noexcept stops here - I do not=
 propose to add explicit operator.<br><br></span></span><b>It is blocking i=
mplementation of the N4387<span style=3D"font-family: courier new,monospace=
;"><span style=3D"font-family: arial,sans-serif;">?<br></span></span></b><s=
pan style=3D"font-family: courier new,monospace;"><span style=3D"font-famil=
y: arial,sans-serif;">No, </span></span><span style=3D"font-family: courier=
 new,monospace;"><span style=3D"font-family: arial,sans-serif;">the paper d=
oes no require any certain implementation. Provision of the conditional exp=
licit will open the way to simpler, non-repeatable implementation. It will =
also simplify the wording.</span></span><b><span style=3D"font-family: cour=
ier new,monospace;"><span style=3D"font-family: arial,sans-serif;"><br><br>=
Does the reduction of writing worth language change?<br></span></span></b><=
span style=3D"font-family: courier new,monospace;"><span style=3D"font-fami=
ly: arial,sans-serif;">I think yes. You may notice that the mentioned paper=
 uses some form of conditional explicit specifier (EXPLICIT) to avoid repea=
ting the specification. If we think that is is worth to add conditional exp=
licit to simplify </span></span><span style=3D"font-family: courier new,mon=
ospace;"><span style=3D"font-family: arial,sans-serif;"><span style=3D"font=
-family: courier new,monospace;"><span style=3D"font-family: arial,sans-ser=
if;">specification</span></span>, I think that is also worth to have one fo=
r code.<br><br>Tomasz Kami=C5=84ski<br></span></span></div>

<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 />

------=_Part_602_1568410384.1429892300256--
------=_Part_601_1570827894.1429892300251--

.


Author: =?ISO-8859-1?Q?Daniel_Kr=FCgler?= <daniel.kruegler@gmail.com>
Date: Fri, 24 Apr 2015 19:23:18 +0200
Raw View
2015-04-24 18:18 GMT+02:00 Tomasz <tomaszkam@gmail.com>:
[..]
> I came up with this idea while reading the N4387: Improving pair and tuple,
> revision 3 paper. This paper proposes that the pair<T,U> to be implicitly
> constructible from the expression {e1, e2} if T is implicitly construtible
> from e1 and U from T2. That means that pair<int,double> may be initialized
> with {1, 2.0}, while the same expression will not be accepted for
> pair<std::chrono::second, std::chrono::minutes>. The solution presented in
> the paper is based on providing the two overloads that differs only in the
> cosntrain and presence of the explicit specifier (bodies are the same)
>
> template<typename T1, typename T2>
>   template<typename U1, typename U2
>            typename = std::enable_if_t<
>              is_construtible<T1, U1&&>{} && is_construtible<T2, U2&&>{} &&
>              is_convertible<U1&&, T1>{} && is_convertible<U2&&, T2>{}
>            >>
> pair<T1, T2>::pair(U1&& u1, U2&& u2);
>
> template<typename T1, typename T2>
>   template<typename U1, typename U2
>            typename = std::enable_if_t<
>              is_construtible<T1, U1&&>{} && is_construtible<T2, U2&&>{} &&
>              !(is_convertible<U1&&, T1>{} && is_convertible<U2&&, T2>{})
>           >>
> explicit pair<T1, T2>::pair(U1&& u1, U2&& u2);
>
> With addition of conditional noexcept, this may be reduced to one overload:
> template<typename T1, typename T2>
>   template<typename U1, typename U2
>            typename = std::enable_if_t<
>                           is_construtible<T1, U1&&>{} && is_construtible<T2,
> U2&&>{}
>           >>
> explicit(!(is_convertible<U1&&, T1>{} && is_convertible<U2&&, T2>{}))
>   pair<T1, T2>::pair(U1&& u1, U2&& u2);
>
> It will also address not such easy to implement case of constructor taking
> T1 and T2 types explicitly, that is discussed in Implementation Hint section
> of the paper.

[..]

> Does the reduction of writing worth language change?
> I think yes. You may notice that the mentioned paper uses some form of
> conditional explicit specifier (EXPLICIT) to avoid repeating the
> specification. If we think that is is worth to add conditional explicit to
> simplify specification, I think that is also worth to have one for code.

I would like to add that

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4387.html

was intentionally worded (a) not to require a library solution for
this (There where some thoughts of gcc implementers that a built-in
intrinsic __explicit(condition) could be provided to realize that
request) and (b) not to require exactly two overloads (see the
rephrased definition of "/EXPLICIT/"). After I submitted my paper I
planned to write a paper with for a conditional explicit core wording
feature as you describe above.

Thanks,

- Daniel

--

---
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/.

.