Topic: Make std::optional a literal type?
Author: =?UTF-8?Q?Andrzej_Krzemie=C5=84ski?= <akrzemi1@gmail.com>
Date: Tue, 20 Nov 2012 08:14:13 -0800 (PST)
Raw View
------=_Part_241_18983739.1353428053760
Content-Type: text/plain; charset=ISO-8859-1
Hi,
I already asked this question in another thread but didn't receive much
feedback probably because I asked in an already old thread. So let me try
again.
The feedback we obtained from LWG (similar to Jeremiah Willcock's
suggestion in this list) was that optional<T> should be made a literal type
for "simple enough" T's. "Simple enough" naturally means
TriviallyDestructible. We did not propose making optional<T> a literal type
because it is not possible (at least to our knowledge) to implement it
decently: there is no way to make optional<T>'s move and copy constructors
constexpr in general, and even in case of TriviallyCopyable types doing so
may affect their run-time performance (depending on the value sizeof(T)).
This is explained in detail in this thread:
https://groups.google.com/a/isocpp.org/d/topic/std-proposals/SX_oPTPPZ_w/discussion
Sympathizing with Jeffrey Yasskin's opinion tat optional's proposal should
not rely on any language change proposal, the options to move forward I can
see are:
1. Do not make optional<T> a literal type.
2. Make optional<T> a literal type for TriviallyDestructible Ts but
leave copy and move constructor non-constexpr.
3. Require that move and copy constructors are constexpr only for types
that are both TriviallyDestructible and TriviallyCopyable. This can be
implemented by using union's compiler-generated copy-constructor. (We use
memcopy regardless if optional is engaged or not). But even this can make
optional's copy constructor ineffective in case sizeof(T) is big.
4. Make move and copy constructors constexpr based on three conditions:
TriviallyDestructible<T> && TriviallyCopyable<T> && SmallEnough<sizeof(T)>,
but this seams too impredictable.
My personal feeling is that the first two options are most clear. But I
feel we need more guidelines from LWG, and LWG members are on this list.
We are interested also in private opinions.
Regards,
&rzej
--
------=_Part_241_18983739.1353428053760
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
Hi,<br>I already asked this question in another thread but didn't receive m=
uch feedback probably because I asked in an already old thread. So let me t=
ry again.<br><br>The feedback we obtained from LWG (similar to Jeremiah Wil=
lcock's suggestion in this list) was that optional<T> should be made =
a literal type for "simple enough" T's. "Simple enough" naturally means Tri=
viallyDestructible. We did not propose making optional<T> a literal t=
ype because it is not possible (at least to our knowledge) to implement it =
decently: there is no way to make optional<T>'s move and copy constru=
ctors constexpr in general, and even in case of TriviallyCopyable types doi=
ng so may affect their run-time performance (depending on the value sizeof(=
T)). This is explained in detail in this thread:<br><br><a href=3D"https://=
groups.google.com/a/isocpp.org/d/topic/std-proposals/SX_oPTPPZ_w/discussion=
">https://groups.google.com/a/isocpp.org/d/topic/std-proposals/SX_oPTPPZ_w/=
discussion</a><br><br>Sympathizing with Jeffrey Yasskin's opinion tat optio=
nal's proposal should not rely on any language change proposal, the options=
to move forward I can see are:<br><br><ol><li>Do not make optional<T>=
; a literal type.</li><li>Make optional<T> a literal type for Trivial=
lyDestructible Ts but leave copy and move constructor non-constexpr.</li><l=
i>Require that move and copy constructors are constexpr only for types that=
are both TriviallyDestructible and TriviallyCopyable. This can be implemen=
ted by using union's compiler-generated copy-constructor. (We use memcopy r=
egardless if optional is engaged or not). But even this can make optional's=
copy constructor ineffective in case sizeof(T) is big.</li><li>Make move a=
nd copy constructors constexpr based on three conditions: TriviallyDestruct=
ible<T> && TriviallyCopyable<T> && SmallEnough&=
lt;sizeof(T)>, but this seams too impredictable.</li></ol><br>My persona=
l feeling is that the first two options are most clear. But I feel we need =
more guidelines from LWG, and LWG members are on this list. <br><br>We are =
interested also in private opinions. <br><br>Regards,<br>&rzej<br> =
;<br>
<p></p>
-- <br />
<br />
<br />
<br />
------=_Part_241_18983739.1353428053760--
.
Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Tue, 20 Nov 2012 18:47:26 +0200
Raw View
On 20 November 2012 18:14, Andrzej Krzemie=F1ski <akrzemi1@gmail.com> wrote=
:
> Do not make optional<T> a literal type.
> Make optional<T> a literal type for TriviallyDestructible Ts but leave co=
py
> and move constructor non-constexpr.
> Require that move and copy constructors are constexpr only for types that
> are both TriviallyDestructible and TriviallyCopyable. This can be
> implemented by using union's compiler-generated copy-constructor. (We use
> memcopy regardless if optional is engaged or not). But even this can make
> optional's copy constructor ineffective in case sizeof(T) is big.
> Make move and copy constructors constexpr based on three conditions:
> TriviallyDestructible<T> && TriviallyCopyable<T> && SmallEnough<sizeof(T)=
>,
> but this seams too impredictable.
I have no strong preference between these options. I do have a strong
preference to
get optional into C++ (hopefully 14), literal or not.
--=20
.
Author: Nevin Liber <nliber@gmail.com>
Date: Tue, 20 Nov 2012 11:05:15 -0600
Raw View
On Nov 20, 2012, at 10:47 AM, Ville Voutilainen
<ville.voutilainen@gmail.com> wrote:
> I have no strong preference between these options. I do have a strong
> preference to
> get optional into C++ (hopefully 14), literal or not.
+1 on both points.
--
.
Author: Richard Smith <richard@metafoo.co.uk>
Date: Tue, 20 Nov 2012 12:54:15 -0800
Raw View
On Tue, Nov 20, 2012 at 8:14 AM, Andrzej Krzemie=F1ski <akrzemi1@gmail.com>=
wrote:
> Hi,
> I already asked this question in another thread but didn't receive much
> feedback probably because I asked in an already old thread. So let me try
> again.
>
> The feedback we obtained from LWG (similar to Jeremiah Willcock's suggest=
ion
> in this list) was that optional<T> should be made a literal type for "sim=
ple
> enough" T's. "Simple enough" naturally means TriviallyDestructible. We di=
d
> not propose making optional<T> a literal type because it is not possible =
(at
> least to our knowledge) to implement it decently: there is no way to make
> optional<T>'s move and copy constructors constexpr in general, and even i=
n
> case of TriviallyCopyable types doing so may affect their run-time
> performance (depending on the value sizeof(T)). This is explained in deta=
il
> in this thread:
>
> https://groups.google.com/a/isocpp.org/d/topic/std-proposals/SX_oPTPPZ_w/=
discussion
>
> Sympathizing with Jeffrey Yasskin's opinion tat optional's proposal shoul=
d
> not rely on any language change proposal, the options to move forward I c=
an
> see are:
>
> Do not make optional<T> a literal type.
> Make optional<T> a literal type for TriviallyDestructible Ts but leave co=
py
> and move constructor non-constexpr.
> Require that move and copy constructors are constexpr only for types that
> are both TriviallyDestructible and TriviallyCopyable. This can be
> implemented by using union's compiler-generated copy-constructor. (We use
> memcopy regardless if optional is engaged or not). But even this can make
> optional's copy constructor ineffective in case sizeof(T) is big.
> Make move and copy constructors constexpr based on three conditions:
> TriviallyDestructible<T> && TriviallyCopyable<T> && SmallEnough<sizeof(T)=
>,
> but this seams too impredictable.
I don't see any significant disadvantage in option 2, if you're
prepared to put in the work to update the paper. I think you should
aim for that as a baseline for constexpr support in std::optional.
Additionally, I think you should strongly consider option 3. Having a
trivial copy constructor has advantages beyond constexpr: for
instance, it allows a memcpy to be used when copying larger structures
containing a std::optional subobject, rather than resorting to a
memberwise copy.
--=20
.
Author: =?UTF-8?Q?Andrzej_Krzemie=C5=84ski?= <akrzemi1@gmail.com>
Date: Wed, 21 Nov 2012 00:26:57 -0800 (PST)
Raw View
------=_Part_174_7251509.1353486418007
Content-Type: text/plain; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable
W dniu wtorek, 20 listopada 2012 21:54:18 UTC+1 u=BFytkownik Richard Smith=
=20
napisa=B3:
>
> On Tue, Nov 20, 2012 at 8:14 AM, Andrzej Krzemie=F1ski <akrz...@gmail.com=
<javascript:>>=20
> wrote:=20
> > Hi,=20
> > I already asked this question in another thread but didn't receive much=
=20
> > feedback probably because I asked in an already old thread. So let me=
=20
> try=20
> > again.=20
> >=20
> > The feedback we obtained from LWG (similar to Jeremiah Willcock's=20
> suggestion=20
> > in this list) was that optional<T> should be made a literal type for=20
> "simple=20
> > enough" T's. "Simple enough" naturally means TriviallyDestructible. We=
=20
> did=20
> > not propose making optional<T> a literal type because it is not possibl=
e=20
> (at=20
> > least to our knowledge) to implement it decently: there is no way to=20
> make=20
> > optional<T>'s move and copy constructors constexpr in general, and even=
=20
> in=20
> > case of TriviallyCopyable types doing so may affect their run-time=20
> > performance (depending on the value sizeof(T)). This is explained in=20
> detail=20
> > in this thread:=20
> >=20
> >=20
> https://groups.google.com/a/isocpp.org/d/topic/std-proposals/SX_oPTPPZ_w/=
discussion=20
> >=20
> > Sympathizing with Jeffrey Yasskin's opinion tat optional's proposal=20
> should=20
> > not rely on any language change proposal, the options to move forward I=
=20
> can=20
> > see are:=20
> >=20
> > Do not make optional<T> a literal type.=20
> > Make optional<T> a literal type for TriviallyDestructible Ts but leave=
=20
> copy=20
> > and move constructor non-constexpr.=20
> > Require that move and copy constructors are constexpr only for types=20
> that=20
> > are both TriviallyDestructible and TriviallyCopyable. This can be=20
> > implemented by using union's compiler-generated copy-constructor. (We=
=20
> use=20
> > memcopy regardless if optional is engaged or not). But even this can=20
> make=20
> > optional's copy constructor ineffective in case sizeof(T) is big.=20
> > Make move and copy constructors constexpr based on three conditions:=20
> > TriviallyDestructible<T> && TriviallyCopyable<T> &&=20
> SmallEnough<sizeof(T)>,=20
> > but this seams too impredictable.=20
>
> I don't see any significant disadvantage in option 2, if you're=20
> prepared to put in the work to update the paper. I think you should=20
> aim for that as a baseline for constexpr support in std::optional.=20
>
> Additionally, I think you should strongly consider option 3. Having a=20
> trivial copy constructor has advantages beyond constexpr: for=20
> instance, it allows a memcpy to be used when copying larger structures=20
> containing a std::optional subobject, rather than resorting to a=20
> memberwise copy.=20
>
I can see the advantages. However, this can also incur run-time cost. Even=
=20
if we have a large TriviallyCopyable T, copying a disengaged optional is=20
way cheaper if we copy non-tivially.
--=20
------=_Part_174_7251509.1353486418007
Content-Type: text/html; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable
<br><br>W dniu wtorek, 20 listopada 2012 21:54:18 UTC+1 u=BFytkownik Richar=
d Smith napisa=B3:<blockquote class=3D"gmail_quote" style=3D"margin: 0;marg=
in-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On Tue, Nov =
20, 2012 at 8:14 AM, Andrzej Krzemie=F1ski <<a href=3D"javascript:" targ=
et=3D"_blank" gdf-obfuscated-mailto=3D"bO3G-Rq042MJ">akrz...@gmail.com</a>&=
gt; wrote:
<br>> Hi,
<br>> I already asked this question in another thread but didn't receive=
much
<br>> feedback probably because I asked in an already old thread. So let=
me try
<br>> again.
<br>>
<br>> The feedback we obtained from LWG (similar to Jeremiah Willcock's =
suggestion
<br>> in this list) was that optional<T> should be made a literal =
type for "simple
<br>> enough" T's. "Simple enough" naturally means TriviallyDestructible=
.. We did
<br>> not propose making optional<T> a literal type because it is =
not possible (at
<br>> least to our knowledge) to implement it decently: there is no way =
to make
<br>> optional<T>'s move and copy constructors constexpr in genera=
l, and even in
<br>> case of TriviallyCopyable types doing so may affect their run-time
<br>> performance (depending on the value sizeof(T)). This is explained =
in detail
<br>> in this thread:
<br>>
<br>> <a href=3D"https://groups.google.com/a/isocpp.org/d/topic/std-prop=
osals/SX_oPTPPZ_w/discussion" target=3D"_blank">https://groups.google.com/a=
/<wbr>isocpp.org/d/topic/std-<wbr>proposals/SX_oPTPPZ_w/<wbr>discussion</a>
<br>>
<br>> Sympathizing with Jeffrey Yasskin's opinion tat optional's proposa=
l should
<br>> not rely on any language change proposal, the options to move forw=
ard I can
<br>> see are:
<br>>
<br>> Do not make optional<T> a literal type.
<br>> Make optional<T> a literal type for TriviallyDestructible Ts=
but leave copy
<br>> and move constructor non-constexpr.
<br>> Require that move and copy constructors are constexpr only for typ=
es that
<br>> are both TriviallyDestructible and TriviallyCopyable. This can be
<br>> implemented by using union's compiler-generated copy-constructor. =
(We use
<br>> memcopy regardless if optional is engaged or not). But even this c=
an make
<br>> optional's copy constructor ineffective in case sizeof(T) is big.
<br>> Make move and copy constructors constexpr based on three condition=
s:
<br>> TriviallyDestructible<T> && TriviallyCopyable<T&g=
t; && SmallEnough<sizeof(T)>,
<br>> but this seams too impredictable.
<br>
<br>I don't see any significant disadvantage in option 2, if you're
<br>prepared to put in the work to update the paper. I think you should
<br>aim for that as a baseline for constexpr support in std::optional.
<br>
<br>Additionally, I think you should strongly consider option 3. Having a
<br>trivial copy constructor has advantages beyond constexpr: for
<br>instance, it allows a memcpy to be used when copying larger structures
<br>containing a std::optional subobject, rather than resorting to a
<br>memberwise copy.
<br></blockquote><div><br>I can see the advantages. However, this can also =
incur run-time cost. Even if we have a large TriviallyCopyable T, copying a=
disengaged optional is way cheaper if we copy non-tivially.<br></div>
<p></p>
-- <br />
<br />
<br />
<br />
------=_Part_174_7251509.1353486418007--
.
Author: Jeffrey Yasskin <jyasskin@googlers.com>
Date: Wed, 21 Nov 2012 09:26:33 -0800
Raw View
On Wed, Nov 21, 2012 at 12:26 AM, Andrzej Krzemie=F1ski
<akrzemi1@gmail.com> wrote:
>
>
> W dniu wtorek, 20 listopada 2012 21:54:18 UTC+1 u=BFytkownik Richard Smit=
h
> napisa=B3:
>>
>> On Tue, Nov 20, 2012 at 8:14 AM, Andrzej Krzemie=F1ski <akrz...@gmail.co=
m>
>> wrote:
>> > Hi,
>> > I already asked this question in another thread but didn't receive muc=
h
>> > feedback probably because I asked in an already old thread. So let me
>> > try
>> > again.
>> >
>> > The feedback we obtained from LWG (similar to Jeremiah Willcock's
>> > suggestion
>> > in this list) was that optional<T> should be made a literal type for
>> > "simple
>> > enough" T's. "Simple enough" naturally means TriviallyDestructible. We
>> > did
>> > not propose making optional<T> a literal type because it is not possib=
le
>> > (at
>> > least to our knowledge) to implement it decently: there is no way to
>> > make
>> > optional<T>'s move and copy constructors constexpr in general, and eve=
n
>> > in
>> > case of TriviallyCopyable types doing so may affect their run-time
>> > performance (depending on the value sizeof(T)). This is explained in
>> > detail
>> > in this thread:
>> >
>> >
>> > https://groups.google.com/a/isocpp.org/d/topic/std-proposals/SX_oPTPPZ=
_w/discussion
>> >
>> > Sympathizing with Jeffrey Yasskin's opinion tat optional's proposal
>> > should
>> > not rely on any language change proposal, the options to move forward =
I
>> > can
>> > see are:
>> >
>> > Do not make optional<T> a literal type.
>> > Make optional<T> a literal type for TriviallyDestructible Ts but leave
>> > copy
>> > and move constructor non-constexpr.
>> > Require that move and copy constructors are constexpr only for types
>> > that
>> > are both TriviallyDestructible and TriviallyCopyable. This can be
>> > implemented by using union's compiler-generated copy-constructor. (We
>> > use
>> > memcopy regardless if optional is engaged or not). But even this can
>> > make
>> > optional's copy constructor ineffective in case sizeof(T) is big.
>> > Make move and copy constructors constexpr based on three conditions:
>> > TriviallyDestructible<T> && TriviallyCopyable<T> &&
>> > SmallEnough<sizeof(T)>,
>> > but this seams too impredictable.
>>
>> I don't see any significant disadvantage in option 2, if you're
>> prepared to put in the work to update the paper. I think you should
>> aim for that as a baseline for constexpr support in std::optional.
>>
>> Additionally, I think you should strongly consider option 3. Having a
>> trivial copy constructor has advantages beyond constexpr: for
>> instance, it allows a memcpy to be used when copying larger structures
>> containing a std::optional subobject, rather than resorting to a
>> memberwise copy.
>
>
> I can see the advantages. However, this can also incur run-time cost. Eve=
n
> if we have a large TriviallyCopyable T, copying a disengaged optional is =
way
> cheaper if we copy non-tivially.
IMO, large types (types with expensive moves) are fairly rare, so we
don't need to contort the std::optional interface to deal with them.
At most, we should make it possible for implementations to optimize
them as a QoI issue. Given that, I don't like option 4 much.
Even if you pick option 1 or 2, implementations are free to make their
copy constructors trivial, which gets the optimization Richard's
worried about, so I don't think that's an argument for standardizing
option 3.
So, I would probably suggest option 2 since it's the least complicated
that still matches what the LWG thought it wanted in Portland, but I'm
going to vote for the proposal regardless.
Jeffrey
--=20
.
Author: Fernando Cacciola <fernando.cacciola@gmail.com>
Date: Wed, 21 Nov 2012 16:05:19 -0300
Raw View
--047d7b6704cd98c29c04cf060a51
Content-Type: text/plain; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable
I've been "playing around in my head" with the 4 options and I also think
that, for a std proposal, option 2 is the best choice.
Best
On Wed, Nov 21, 2012 at 2:26 PM, Jeffrey Yasskin <jyasskin@googlers.com>wro=
te:
> On Wed, Nov 21, 2012 at 12:26 AM, Andrzej Krzemie=F1ski
> <akrzemi1@gmail.com> wrote:
> >
> >
> > W dniu wtorek, 20 listopada 2012 21:54:18 UTC+1 u=BFytkownik Richard Sm=
ith
> > napisa=B3:
> >>
> >> On Tue, Nov 20, 2012 at 8:14 AM, Andrzej Krzemie=F1ski <akrz...@gmail.=
com
> >
> >> wrote:
> >> > Hi,
> >> > I already asked this question in another thread but didn't receive
> much
> >> > feedback probably because I asked in an already old thread. So let m=
e
> >> > try
> >> > again.
> >> >
> >> > The feedback we obtained from LWG (similar to Jeremiah Willcock's
> >> > suggestion
> >> > in this list) was that optional<T> should be made a literal type for
> >> > "simple
> >> > enough" T's. "Simple enough" naturally means TriviallyDestructible. =
We
> >> > did
> >> > not propose making optional<T> a literal type because it is not
> possible
> >> > (at
> >> > least to our knowledge) to implement it decently: there is no way to
> >> > make
> >> > optional<T>'s move and copy constructors constexpr in general, and
> even
> >> > in
> >> > case of TriviallyCopyable types doing so may affect their run-time
> >> > performance (depending on the value sizeof(T)). This is explained in
> >> > detail
> >> > in this thread:
> >> >
> >> >
> >> >
> https://groups.google.com/a/isocpp.org/d/topic/std-proposals/SX_oPTPPZ_w/=
discussion
> >> >
> >> > Sympathizing with Jeffrey Yasskin's opinion tat optional's proposal
> >> > should
> >> > not rely on any language change proposal, the options to move forwar=
d
> I
> >> > can
> >> > see are:
> >> >
> >> > Do not make optional<T> a literal type.
> >> > Make optional<T> a literal type for TriviallyDestructible Ts but lea=
ve
> >> > copy
> >> > and move constructor non-constexpr.
> >> > Require that move and copy constructors are constexpr only for types
> >> > that
> >> > are both TriviallyDestructible and TriviallyCopyable. This can be
> >> > implemented by using union's compiler-generated copy-constructor. (W=
e
> >> > use
> >> > memcopy regardless if optional is engaged or not). But even this can
> >> > make
> >> > optional's copy constructor ineffective in case sizeof(T) is big.
> >> > Make move and copy constructors constexpr based on three conditions:
> >> > TriviallyDestructible<T> && TriviallyCopyable<T> &&
> >> > SmallEnough<sizeof(T)>,
> >> > but this seams too impredictable.
> >>
> >> I don't see any significant disadvantage in option 2, if you're
> >> prepared to put in the work to update the paper. I think you should
> >> aim for that as a baseline for constexpr support in std::optional.
> >>
> >> Additionally, I think you should strongly consider option 3. Having a
> >> trivial copy constructor has advantages beyond constexpr: for
> >> instance, it allows a memcpy to be used when copying larger structures
> >> containing a std::optional subobject, rather than resorting to a
> >> memberwise copy.
> >
> >
> > I can see the advantages. However, this can also incur run-time cost.
> Even
> > if we have a large TriviallyCopyable T, copying a disengaged optional i=
s
> way
> > cheaper if we copy non-tivially.
>
> IMO, large types (types with expensive moves) are fairly rare, so we
> don't need to contort the std::optional interface to deal with them.
> At most, we should make it possible for implementations to optimize
> them as a QoI issue. Given that, I don't like option 4 much.
>
> Even if you pick option 1 or 2, implementations are free to make their
> copy constructors trivial, which gets the optimization Richard's
> worried about, so I don't think that's an argument for standardizing
> option 3.
>
> So, I would probably suggest option 2 since it's the least complicated
> that still matches what the LWG thought it wanted in Portland, but I'm
> going to vote for the proposal regardless.
>
> Jeffrey
>
> --
>
>
>
>
--=20
Fernando Cacciola
SciSoft Consulting, Founder
http://www.scisoft-consulting.com
--=20
--047d7b6704cd98c29c04cf060a51
Content-Type: text/html; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable
I've been "playing around in my head" with the 4 options and =
I also think that, for a std proposal, option 2 is the best choice.<br><br>=
<br>Best<br><div class=3D"gmail_extra"><br><br><div class=3D"gmail_quote">O=
n Wed, Nov 21, 2012 at 2:26 PM, Jeffrey Yasskin <span dir=3D"ltr"><<a hr=
ef=3D"mailto:jyasskin@googlers.com" target=3D"_blank">jyasskin@googlers.com=
</a>></span> wrote:<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><div class=3D"HOEnZb"><div class=3D"h5">On W=
ed, Nov 21, 2012 at 12:26 AM, Andrzej Krzemie=F1ski<br>
<<a href=3D"mailto:akrzemi1@gmail.com">akrzemi1@gmail.com</a>> wrote:=
<br>
><br>
><br>
> W dniu wtorek, 20 listopada 2012 21:54:18 UTC+1 u=BFytkownik Richard S=
mith<br>
> napisa=B3:<br>
>><br>
>> On Tue, Nov 20, 2012 at 8:14 AM, Andrzej Krzemie=F1ski <<a href=
=3D"mailto:akrz...@gmail.com">akrz...@gmail.com</a>><br>
>> wrote:<br>
>> > Hi,<br>
>> > I already asked this question in another thread but didn'=
t receive much<br>
>> > feedback probably because I asked in an already old thread. S=
o let me<br>
>> > try<br>
>> > again.<br>
>> ><br>
>> > The feedback we obtained from LWG (similar to Jeremiah Willco=
ck's<br>
>> > suggestion<br>
>> > in this list) was that optional<T> should be made a lit=
eral type for<br>
>> > "simple<br>
>> > enough" T's. "Simple enough" naturally mea=
ns TriviallyDestructible. We<br>
>> > did<br>
>> > not propose making optional<T> a literal type because i=
t is not possible<br>
>> > (at<br>
>> > least to our knowledge) to implement it decently: there is no=
way to<br>
>> > make<br>
>> > optional<T>'s move and copy constructors constexpr =
in general, and even<br>
>> > in<br>
>> > case of TriviallyCopyable types doing so may affect their run=
-time<br>
>> > performance (depending on the value sizeof(T)). This is expla=
ined in<br>
>> > detail<br>
>> > in this thread:<br>
>> ><br>
>> ><br>
>> > <a href=3D"https://groups.google.com/a/isocpp.org/d/topic/std=
-proposals/SX_oPTPPZ_w/discussion" target=3D"_blank">https://groups.google.=
com/a/isocpp.org/d/topic/std-proposals/SX_oPTPPZ_w/discussion</a><br>
>> ><br>
>> > Sympathizing with Jeffrey Yasskin's opinion tat optional&=
#39;s proposal<br>
>> > should<br>
>> > not rely on any language change proposal, the options to move=
forward I<br>
>> > can<br>
>> > see are:<br>
>> ><br>
>> > Do not make optional<T> a literal type.<br>
>> > Make optional<T> a literal type for TriviallyDestructib=
le Ts but leave<br>
>> > copy<br>
>> > and move constructor non-constexpr.<br>
>> > Require that move and copy constructors are constexpr only fo=
r types<br>
>> > that<br>
>> > are both TriviallyDestructible and TriviallyCopyable. This ca=
n be<br>
>> > implemented by using union's compiler-generated copy-cons=
tructor. (We<br>
>> > use<br>
>> > memcopy regardless if optional is engaged or not). But even t=
his can<br>
>> > make<br>
>> > optional's copy constructor ineffective in case sizeof(T)=
is big.<br>
>> > Make move and copy constructors constexpr based on three cond=
itions:<br>
>> > TriviallyDestructible<T> && TriviallyCopyable&l=
t;T> &&<br>
>> > SmallEnough<sizeof(T)>,<br>
>> > but this seams too impredictable.<br>
>><br>
>> I don't see any significant disadvantage in option 2, if you&#=
39;re<br>
>> prepared to put in the work to update the paper. I think you shoul=
d<br>
>> aim for that as a baseline for constexpr support in std::optional.=
<br>
>><br>
>> Additionally, I think you should strongly consider option 3. Havin=
g a<br>
>> trivial copy constructor has advantages beyond constexpr: for<br>
>> instance, it allows a memcpy to be used when copying larger struct=
ures<br>
>> containing a std::optional subobject, rather than resorting to a<b=
r>
>> memberwise copy.<br>
><br>
><br>
> I can see the advantages. However, this can also incur run-time cost. =
Even<br>
> if we have a large TriviallyCopyable T, copying a disengaged optional =
is way<br>
> cheaper if we copy non-tivially.<br>
<br>
</div></div>IMO, large types (types with expensive moves) are fairly rare, =
so we<br>
don't need to contort the std::optional interface to deal with them.<br=
>
At most, we should make it possible for implementations to optimize<br>
them as a QoI issue. Given that, I don't like option 4 much.<br>
<br>
Even if you pick option 1 or 2, implementations are free to make their<br>
copy constructors trivial, which gets the optimization Richard's<br>
worried about, so I don't think that's an argument for standardizin=
g<br>
option 3.<br>
<br>
So, I would probably suggest option 2 since it's the least complicated<=
br>
that still matches what the LWG thought it wanted in Portland, but I'm<=
br>
going to vote for the proposal regardless.<br>
<span class=3D"HOEnZb"><font color=3D"#888888"><br>
Jeffrey<br>
<br>
--<br>
<br>
<br>
<br>
</font></span></blockquote></div><br><br clear=3D"all"><br>-- <br>Fernando =
Cacciola<br>SciSoft Consulting, Founder<br><a href=3D"http://www.scisoft-co=
nsulting.com">http://www.scisoft-consulting.com</a><br>
</div>
<p></p>
-- <br />
<br />
<br />
<br />
--047d7b6704cd98c29c04cf060a51--
.
Author: =?UTF-8?Q?Andrzej_Krzemie=C5=84ski?= <akrzemi1@gmail.com>
Date: Fri, 23 Nov 2012 05:57:51 -0800 (PST)
Raw View
------=_Part_673_27053954.1353679071451
Content-Type: text/plain; charset=ISO-8859-1
> So, I would probably suggest option 2 since it's the least complicated
> that still matches what the LWG thought it wanted in Portland, but I'm
> going to vote for the proposal regardless.
>
We will propose option 2 then. I have one other question to the Standard
experts. How should we express in the standardese the requirement that
certain operations must be evaluable at compile-time? The way 'constexpr'
is defined, (7.1.5 para 6) if you declare a function template constexpr you
are not required (neither by the library standardese nor by the language)
that the instantiations of your template to be constexpr functions
(provided that there exists only one single instantiation that is in fact a
constexpr function).
To illustrate what I mean, if n3471 is incorporated, the standardese for
20.3.3 (tuple comparison) would read:
template <class T1, class T2>
constexpr bool operator==(const pair<T1, T2>& x, const pair<T1, T2>& y);
*Returns: *x.first == y.first && x.second == y.second.
But it does not require of the operator that p == p is a core constant
expression even if decltype(p) is pair<int, int>. Because constexpr
function template instantiations are not required to render constexpr
functions.
We would still have to add a requirement that instantiations of this
templates shall render constexpr functions for all types for which T1's and
T2's operator== are constexpr functions. Am I right?
--
------=_Part_673_27053954.1353679071451
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<br><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex=
;border-left: 1px #ccc solid;padding-left: 1ex;">So, I would probably sugge=
st option 2 since it's the least complicated
<br>that still matches what the LWG thought it wanted in Portland, but I'm
<br>going to vote for the proposal regardless.
<br></blockquote><div><br>We will propose option 2 then. I have one other q=
uestion to the Standard experts. How should we express in the standardese t=
he requirement that certain operations must be evaluable at compile-time? T=
he way 'constexpr' is defined, (7.1.5 para 6) if you declare a function tem=
plate constexpr you are not required (neither by the library standardese no=
r by the language) that the instantiations of your template to be constexpr=
functions (provided that there exists only one single instantiation that i=
s in fact a constexpr function). <br><br>To illustrate what I mean, if n347=
1 is incorporated, the standardese for 20.3.3 (tuple comparison) would read=
:<br><br><div style=3D"margin-left: 40px;"><span style=3D"font-family: cour=
ier new,monospace;">template <class T1, class T2></span><br><span sty=
le=3D"font-family: courier new,monospace;"> constexpr bool operator=
=3D=3D(const pair<T1, T2>& x, const pair<T1, T2>& y);</=
span><br><br> <i>Returns: </i><span style=
=3D"font-family: courier new,monospace;">x.first =3D=3D y.first && =
x.second =3D=3D y.second</span>.<br></div> <br>But it does not require of t=
he operator that <span style=3D"font-family: courier new,monospace;">p =3D=
=3D p</span> is a core constant expression even if <span style=3D"font-fami=
ly: courier new,monospace;">decltype(p)</span> is <span style=3D"font-famil=
y: courier new,monospace;">pair<int, int></span>. Because const=
expr function template instantiations are not required to render constexpr =
functions.<br><br>We would still have to add a requirement that instantiati=
ons of this templates shall render constexpr functions for all types for wh=
ich <span style=3D"font-family: courier new,monospace;">T1</span>'s and <sp=
an style=3D"font-family: courier new,monospace;">T2</span>'s operator=3D=3D=
are constexpr functions. Am I right?<br><br></div>
<p></p>
-- <br />
<br />
<br />
<br />
------=_Part_673_27053954.1353679071451--
.
Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Fri, 23 Nov 2012 16:04:16 +0200
Raw View
On 23 November 2012 15:57, Andrzej Krzemie=C5=84ski <akrzemi1@gmail.com> wr=
ote:
> But it does not require of the operator that p =3D=3D p is a core constan=
t
> expression even if decltype(p) is pair<int, int>. Because constexpr
> function template instantiations are not required to render constexpr
> functions.
> We would still have to add a requirement that instantiations of this
> templates shall render constexpr functions for all types for which T1's a=
nd
> T2's operator=3D=3D are constexpr functions. Am I right?
I would think you want to say that optional is literal if its underlying ty=
pe is
literal. We probably don't want to repeat such a generic requirement for
every operation.
--=20
.
Author: =?UTF-8?Q?Andrzej_Krzemie=C5=84ski?= <akrzemi1@gmail.com>
Date: Fri, 23 Nov 2012 06:21:11 -0800 (PST)
Raw View
------=_Part_291_18899752.1353680471874
Content-Type: text/plain; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable
W dniu pi=B1tek, 23 listopada 2012 15:04:18 UTC+1 u=BFytkownik Ville=20
Voutilainen napisa=B3:
>
> On 23 November 2012 15:57, Andrzej Krzemie=F1ski <akrz...@gmail.com<javas=
cript:>>=20
> wrote:=20
> > But it does not require of the operator that p =3D=3D p is a core const=
ant=20
> > expression even if decltype(p) is pair<int, int>. Because constexpr=20
> > function template instantiations are not required to render constexpr=
=20
> > functions.=20
> > We would still have to add a requirement that instantiations of this=20
> > templates shall render constexpr functions for all types for which T1's=
=20
> and=20
> > T2's operator=3D=3D are constexpr functions. Am I right?=20
>
> I would think you want to say that optional is literal if its underlying=
=20
> type is=20
> literal. We probably don't want to repeat such a generic requirement for=
=20
> every operation.=20
>
I want to say something more (I think). Being a literal type (according to=
=20
my understanding) only guarantees:
- my sub-objects are literal types=20
- I have trivial destructor
- I have one constexpr constructor
In particular it does not guarantee that any observer functions are=20
constexpr functions.
--=20
------=_Part_291_18899752.1353680471874
Content-Type: text/html; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable
<br><br>W dniu pi=B1tek, 23 listopada 2012 15:04:18 UTC+1 u=BFytkownik Vill=
e Voutilainen napisa=B3:<blockquote class=3D"gmail_quote" style=3D"margin: =
0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On 23 =
November 2012 15:57, Andrzej Krzemie=F1ski <<a href=3D"javascript:" targ=
et=3D"_blank" gdf-obfuscated-mailto=3D"PyUNyGOVJbcJ">akrz...@gmail.com</a>&=
gt; wrote:
<br>> But it does not require of the operator that p =3D=3D p is a core =
constant
<br>> expression even if decltype(p) is pair<int, int>. Beca=
use constexpr
<br>> function template instantiations are not required to render conste=
xpr
<br>> functions.
<br>> We would still have to add a requirement that instantiations of th=
is
<br>> templates shall render constexpr functions for all types for which=
T1's and
<br>> T2's operator=3D=3D are constexpr functions. Am I right?
<br>
<br>I would think you want to say that optional is literal if its underlyin=
g type is
<br>literal. We probably don't want to repeat such a generic requirement fo=
r
<br>every operation.
<br></blockquote><div><br>I want to say something more (I think). Being a l=
iteral type (according to my understanding) only guarantees:<br><ul><li>my =
sub-objects are literal types </li><li>I have trivial destructor</li><=
li>I have one constexpr constructor</li></ul><p>In particular it does not g=
uarantee that any observer functions are constexpr functions.<br></p></div>
<p></p>
-- <br />
<br />
<br />
<br />
------=_Part_291_18899752.1353680471874--
.
Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Fri, 23 Nov 2012 16:36:09 +0200
Raw View
On 23 November 2012 16:21, Andrzej Krzemie=C5=84ski <akrzemi1@gmail.com> wr=
ote:
> I want to say something more (I think). Being a literal type (according t=
o
> my understanding) only guarantees:
> my sub-objects are literal types
> I have trivial destructor
> I have one constexpr constructor
> In particular it does not guarantee that any observer functions are
> constexpr functions.
I thought we weren't aiming to make the observer functions constexpr.
--=20
.
Author: =?UTF-8?Q?Andrzej_Krzemie=C5=84ski?= <akrzemi1@gmail.com>
Date: Fri, 23 Nov 2012 06:47:47 -0800 (PST)
Raw View
------=_Part_118_31432494.1353682067642
Content-Type: text/plain; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable
W dniu pi=B1tek, 23 listopada 2012 15:36:10 UTC+1 u=BFytkownik Ville=20
Voutilainen napisa=B3:
>
> On 23 November 2012 16:21, Andrzej Krzemie=F1ski <akrz...@gmail.com<javas=
cript:>>=20
> wrote:=20
> > I want to say something more (I think). Being a literal type (according=
=20
> to=20
> > my understanding) only guarantees:=20
> > my sub-objects are literal types=20
> > I have trivial destructor=20
> > I have one constexpr constructor=20
> > In particular it does not guarantee that any observer functions are=20
> > constexpr functions.=20
>
> I thought we weren't aiming to make the observer functions constexpr.=20
>
Regarding our proposal, the greatest effort is to provide a reference=20
implementation and after going through the trouble of making optional a=20
literal type, adding constexpr observers comes nearly for free.
Regarding the usefulness of the optional. Given that people will want to=20
create them at compile-time they will probably also want to inspect them at=
=20
compile-time.=20
But even if we leave the observer functions aside, by requiring that=20
Optional<T> is a literal type, we are only requiring that one (some)=20
constructor is constexpr: the others can be legally only declared with=20
"constexpr" specifier but not be constexpr constructors. -- At least this=
=20
is how I understand the standard.
--=20
------=_Part_118_31432494.1353682067642
Content-Type: text/html; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable
<br><br>W dniu pi=B1tek, 23 listopada 2012 15:36:10 UTC+1 u=BFytkownik Vill=
e Voutilainen napisa=B3:<blockquote class=3D"gmail_quote" style=3D"margin: =
0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On 23 =
November 2012 16:21, Andrzej Krzemie=F1ski <<a href=3D"javascript:" targ=
et=3D"_blank" gdf-obfuscated-mailto=3D"zV7-dvTFAJEJ">akrz...@gmail.com</a>&=
gt; wrote:
<br>> I want to say something more (I think). Being a literal type (acco=
rding to
<br>> my understanding) only guarantees:
<br>> my sub-objects are literal types
<br>> I have trivial destructor
<br>> I have one constexpr constructor
<br>> In particular it does not guarantee that any observer functions ar=
e
<br>> constexpr functions.
<br>
<br>I thought we weren't aiming to make the observer functions constexpr.
<br></blockquote><div><br>Regarding our proposal, the greatest effort is to=
provide a reference implementation and after going through the trouble of =
making optional a literal type, adding constexpr observers comes nearly for=
free.<br><br>Regarding the usefulness of the optional. Given that people w=
ill want to create them at compile-time they will probably also want to ins=
pect them at compile-time. <br><br>But even if we leave the observer functi=
ons aside, by requiring that Optional<T> is a literal type, we are on=
ly requiring that one (some) constructor is constexpr: the others can be le=
gally only declared with "constexpr" specifier but not be constexpr constru=
ctors. -- At least this is how I understand the standard.<br></div>
<p></p>
-- <br />
<br />
<br />
<br />
------=_Part_118_31432494.1353682067642--
.
Author: Fernando Cacciola <fernando.cacciola@gmail.com>
Date: Fri, 23 Nov 2012 11:52:31 -0300
Raw View
--e89a8f8396e31918f204cf2abecc
Content-Type: text/plain; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable
On Fri, Nov 23, 2012 at 12:21 PM, Andrzej Krzemie=F1ski <akrzemi1@gmail.com=
>wrote:
>
>
> W dniu pi=B1tek, 23 listopada 2012 15:04:18 UTC+1 u=BFytkownik Ville
> Voutilainen napisa=B3:
>
>> On 23 November 2012 15:57, Andrzej Krzemie=F1ski <akrz...@gmail.com>
>> wrote:
>> > But it does not require of the operator that p =3D=3D p is a core cons=
tant
>> > expression even if decltype(p) is pair<int, int>. Because constexpr
>> > function template instantiations are not required to render constexpr
>> > functions.
>> > We would still have to add a requirement that instantiations of this
>> > templates shall render constexpr functions for all types for which T1'=
s
>> and
>> > T2's operator=3D=3D are constexpr functions. Am I right?
>>
>> I would think you want to say that optional is literal if its underlying
>> type is
>> literal. We probably don't want to repeat such a generic requirement for
>> every operation.
>>
>
> I want to say something more (I think). Being a literal type (according t=
o
> my understanding) only guarantees:
>
> - my sub-objects are literal types
> - I have trivial destructor
> - I have one constexpr constructor
>
>
I have the same understanding.
Though I would say that this is effectively equivalent to what Ville said,
just more formal.
> In particular it does not guarantee that any observer functions are
> constexpr functions.
>
Right.
Neither that the move/copy ctor is constexpr, which is why I liked option 2=
..
>We would still have to add a requirement that instantiations of this
templates shall render constexpr functions for all types for which T1's and
T2's operator=3D=3D are constexpr >functions. Am I right?
I don't think so, not in the way you are saying it.
We should define certain functions (and operators, and member functions) as
constexpr but that imposes no requirements in the instantiations (if the
instantiation fails to satisfy the requirements for a constexpr then it's
just not constexpr, and the program will be ill-formed only if it the
optional<> is attempted to be used as constant expression)
--=20
Fernando Cacciola
SciSoft Consulting, Founder
http://www.scisoft-consulting.com
--=20
--e89a8f8396e31918f204cf2abecc
Content-Type: text/html; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable
<br><div class=3D"gmail_extra"><div class=3D"gmail_quote">On Fri, Nov 23, 2=
012 at 12:21 PM, Andrzej Krzemie=F1ski <span dir=3D"ltr"><<a href=3D"mai=
lto:akrzemi1@gmail.com" target=3D"_blank">akrzemi1@gmail.com</a>></span>=
wrote:<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-=
left:1px solid rgb(204,204,204);padding-left:1ex"><br><br>W dniu pi=B1tek, =
23 listopada 2012 15:04:18 UTC+1 u=BFytkownik Ville Voutilainen napisa=B3:<=
div><div class=3D"h5">
<blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-=
left:1px solid rgb(204,204,204);padding-left:1ex">On 23 November 2012 15:57=
, Andrzej Krzemie=F1ski <<a>akrz...@gmail.com</a>> wrote:
<br>> But it does not require of the operator that p =3D=3D p is a core =
constant
<br>> expression even if decltype(p) is pair<int, int>. =A0Because=
constexpr
<br>> function template instantiations are not required to render conste=
xpr
<br>> functions.
<br>> We would still have to add a requirement that instantiations of th=
is
<br>> templates shall render constexpr functions for all types for which=
T1's and
<br>> T2's operator=3D=3D are constexpr functions. Am I right?
<br>
<br>I would think you want to say that optional is literal if its underlyin=
g type is
<br>literal. We probably don't want to repeat such a generic requiremen=
t for
<br>every operation.
<br></blockquote></div></div><div><br>I want to say something more (I think=
). Being a literal type (according to my understanding) only guarantees:<br=
><ul><li>my sub-objects are literal types=A0</li><li>I have trivial destruc=
tor</li>
<li>I have one constexpr constructor</li></ul><p></p></div></blockquote><di=
v><br>I have the same understanding.<br><br>Though I would say that this is=
effectively equivalent to what Ville said, just more formal.<br><div>
<p>
<span class=3D""></span></p></div><span class=3D""><font color=3D"#888888">=
=A0
</font></span><br></div><blockquote class=3D"gmail_quote" style=3D"margin:0=
px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><=
div><p>In particular it does not guarantee that any observer functions are =
constexpr functions.<span class=3D""><font color=3D"#888888"><br>
</font></span></p></div></blockquote><div><br>Right.<br><br>Neither that th=
e move/copy ctor is constexpr, which is why I liked option 2.<br><br></div>=
</div>>We would still have to add a requirement that instantiations of t=
his=20
templates shall render constexpr functions for all types for which <span st=
yle=3D"font-family:courier new,monospace">T1</span>'s and <span style=
=3D"font-family:courier new,monospace">T2</span>'s operator=3D=3D are c=
onstexpr >functions. Am I right?<br>
<br>I don't think so, not in the way you are saying it.<br><br>We shoul=
d define certain functions (and operators, and member functions) as constex=
pr but that imposes no requirements in the instantiations (if the instantia=
tion fails to satisfy the requirements for a constexpr then it's just n=
ot constexpr, and the program will be ill-formed only if it the optional<=
;> is attempted to be used as constant expression)<br>
<br clear=3D"all"><br>-- <br>Fernando Cacciola<br>SciSoft Consulting, Found=
er<br><a href=3D"http://www.scisoft-consulting.com">http://www.scisoft-cons=
ulting.com</a><br>
</div>
<p></p>
-- <br />
<br />
<br />
<br />
--e89a8f8396e31918f204cf2abecc--
.
Author: Fernando Cacciola <fernando.cacciola@gmail.com>
Date: Fri, 23 Nov 2012 11:59:28 -0300
Raw View
--e89a8ff1cb06ec52b804cf2ad65c
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Fri, Nov 23, 2012 at 12:36 PM, Ville Voutilainen <
ville.voutilainen@gmail.com> wrote:
> On 23 November 2012 16:21, Andrzej Krzemie=C5=84ski <akrzemi1@gmail.com> =
wrote:
> > I want to say something more (I think). Being a literal type (according
> to
> > my understanding) only guarantees:
> > my sub-objects are literal types
> > I have trivial destructor
> > I have one constexpr constructor
> > In particular it does not guarantee that any observer functions are
> > constexpr functions.
>
> I thought we weren't aiming to make the observer functions constexpr.
>
>
IIUC, "const" observers such as operator*, operator =3D=3D, etc... should =
be
defined with the constexpr modifier.
The effect is that, with optional<T> being a literal type, in the context
where a const optional of a literal type is used in a expression that calls
such constexpr functions, the result of the call (such as the value of the
optional or the result of a comparison) is a constant expression.
That is:
constexpr optional<int> o(123);
int a[ *o ] ; // This should be OK.
I also understand that the only requirement in terms of the std text is to
include the constexpr specifier where appropriate. I don't think any extra
clarification is needed.
Best
--=20
Fernando Cacciola
SciSoft Consulting, Founder
http://www.scisoft-consulting.com
--=20
--e89a8ff1cb06ec52b804cf2ad65c
Content-Type: text/html; charset=ISO-8859-13
Content-Transfer-Encoding: quoted-printable
<br><div class=3D"gmail_extra"><br><div class=3D"gmail_quote">On Fri, Nov 2=
3, 2012 at 12:36 PM, Ville Voutilainen <span dir=3D"ltr"><<a href=3D"mai=
lto:ville.voutilainen@gmail.com" target=3D"_blank">ville.voutilainen@gmail.=
com</a>></span> wrote:<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><div class=3D"im">On 23 November 2012 16:21,=
Andrzej Krzemie=F1ski <<a href=3D"mailto:akrzemi1@gmail.com">akrzemi1@g=
mail.com</a>> wrote:<br>
> I want to say something more (I think). Being a literal type (accordin=
g to<br>
> my understanding) only guarantees:<br>
> my sub-objects are literal types<br>
> I have trivial destructor<br>
> I have one constexpr constructor<br>
> In particular it does not guarantee that any observer functions are<br=
>
> constexpr functions.<br>
<br>
</div>I thought we weren't aiming to make the observer functions conste=
xpr.<br>
<span class=3D"HOEnZb"><font color=3D"#888888"><br></font></span></blockquo=
te><div><br>IIUC,=A0 "const" observers such as operator*, operato=
r =3D=3D, etc... should be defined with the constexpr modifier.<br><br>The =
effect is that, with optional<T> being a literal type, in the context=
where a const optional of a literal type is used in a expression that call=
s such constexpr functions, the result of the call (such as the value of th=
e optional or the result of a comparison) is a constant expression.<br>
<br>That is:<br><br>constexpr optional<int> o(123);<br><br>int a[ *o =
] ; // This should be OK.<br><br></div></div>I also understand that the onl=
y requirement in terms of the std text is to include the constexpr specifie=
r where appropriate. I don't think any extra clarification is needed.<b=
r>
<br>Best<br clear=3D"all"><br>-- <br>Fernando Cacciola<br>SciSoft Consultin=
g, Founder<br><a href=3D"http://www.scisoft-consulting.com">http://www.scis=
oft-consulting.com</a><br>
</div>
<p></p>
-- <br />
<br />
<br />
<br />
--e89a8ff1cb06ec52b804cf2ad65c--
.
Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Fri, 23 Nov 2012 17:03:38 +0200
Raw View
On 23 November 2012 16:59, Fernando Cacciola
<fernando.cacciola@gmail.com> wrote:
> IIUC, "const" observers such as operator*, operator ==, etc... should be
> defined with the constexpr modifier.
> The effect is that, with optional<T> being a literal type, in the context
> where a const optional of a literal type is used in a expression that calls
> such constexpr functions, the result of the call (such as the value of the
> optional or the result of a comparison) is a constant expression.
> That is:
> constexpr optional<int> o(123);
> int a[ *o ] ; // This should be OK.
> I also understand that the only requirement in terms of the std text is to
> include the constexpr specifier where appropriate. I don't think any extra
> clarification is needed.
Ah, and if it throws an error for a disengaged optional, it's not
constexpr, and that
code would be ill-formed. Seems that we shouldn't need many extra requirements.
--
.
Author: =?UTF-8?Q?Andrzej_Krzemie=C5=84ski?= <akrzemi1@gmail.com>
Date: Fri, 23 Nov 2012 07:17:23 -0800 (PST)
Raw View
------=_Part_369_24118393.1353683843513
Content-Type: text/plain; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable
W dniu pi=B1tek, 23 listopada 2012 15:53:13 UTC+1 u=BFytkownik Fernando=20
Cacciola napisa=B3:
>
>
> On Fri, Nov 23, 2012 at 12:21 PM, Andrzej Krzemie=F1ski <akrz...@gmail.co=
m<javascript:>
> > wrote:
>
>>
>>
>> W dniu pi=B1tek, 23 listopada 2012 15:04:18 UTC+1 u=BFytkownik Ville=20
>> Voutilainen napisa=B3:
>>
>>> On 23 November 2012 15:57, Andrzej Krzemie=F1ski <akrz...@gmail.com>=20
>>> wrote:=20
>>> > But it does not require of the operator that p =3D=3D p is a core con=
stant=20
>>> > expression even if decltype(p) is pair<int, int>. Because constexpr=
=20
>>> > function template instantiations are not required to render constexpr=
=20
>>> > functions.=20
>>> > We would still have to add a requirement that instantiations of this=
=20
>>> > templates shall render constexpr functions for all types for which=20
>>> T1's and=20
>>> > T2's operator=3D=3D are constexpr functions. Am I right?=20
>>>
>>> I would think you want to say that optional is literal if its underlyin=
g=20
>>> type is=20
>>> literal. We probably don't want to repeat such a generic requirement fo=
r=20
>>> every operation.=20
>>>
>>
>> I want to say something more (I think). Being a literal type (according=
=20
>> to my understanding) only guarantees:
>>
>> - my sub-objects are literal types=20
>> - I have trivial destructor=20
>> - I have one constexpr constructor
>>
>>
> I have the same understanding.
>
> Though I would say that this is effectively equivalent to what Ville said=
,=20
> just more formal.
>
> =20
>
>> In particular it does not guarantee that any observer functions are=20
>> constexpr functions.
>>
>
> Right.
>
> Neither that the move/copy ctor is constexpr, which is why I liked option=
=20
> 2.
>
> >We would still have to add a requirement that instantiations of this=20
> templates shall render constexpr functions for all types for which T1's=
=20
> and T2's operator=3D=3D are constexpr >functions. Am I right?
>
> I don't think so, not in the way you are saying it.
>
> We should define certain functions (and operators, and member functions)=
=20
> as constexpr but that imposes no requirements in the instantiations (if t=
he=20
> instantiation fails to satisfy the requirements for a constexpr then it's=
=20
> just not constexpr, and the program will be ill-formed only if it the=20
> optional<> is attempted to be used as constant expression)
>
I agree with your analysis, but this means that a programmer will type this=
=20
code:
constexpr optional<int> oi{1};
constexpr optional<int> oj{1};
static_assert(oi =3D=3D oj, "!");
And he will receive a compiler error saying that operator=3D=3D is not a=20
constexpr function: it has been only defined with constexpr specifier. He=
=20
will accuse the standard library vendor that the library is not compliant=
=20
with C++ Standard. But the vendor will say "the standard only requires that=
=20
we annotate operator=3D=3D with constexpr; but not that these operators mus=
t be=20
constexpr functions".
=20
--=20
------=_Part_369_24118393.1353683843513
Content-Type: text/html; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable
<br><br>W dniu pi=B1tek, 23 listopada 2012 15:53:13 UTC+1 u=BFytkownik Fern=
ando Cacciola napisa=B3:<blockquote class=3D"gmail_quote" style=3D"margin: =
0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><br><d=
iv><div class=3D"gmail_quote">On Fri, Nov 23, 2012 at 12:21 PM, Andrzej Krz=
emie=F1ski <span dir=3D"ltr"><<a href=3D"javascript:" target=3D"_blank" =
gdf-obfuscated-mailto=3D"y4Wg4Gi6ffQJ">akrz...@gmail.com</a>></span> wro=
te:<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-=
left:1px solid rgb(204,204,204);padding-left:1ex"><br><br>W dniu pi=B1tek, =
23 listopada 2012 15:04:18 UTC+1 u=BFytkownik Ville Voutilainen napisa=B3:<=
div><div>
<blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-=
left:1px solid rgb(204,204,204);padding-left:1ex">On 23 November 2012 15:57=
, Andrzej Krzemie=F1ski <<a>akrz...@gmail.com</a>> wrote:
<br>> But it does not require of the operator that p =3D=3D p is a core =
constant
<br>> expression even if decltype(p) is pair<int, int>. Beca=
use constexpr
<br>> function template instantiations are not required to render conste=
xpr
<br>> functions.
<br>> We would still have to add a requirement that instantiations of th=
is
<br>> templates shall render constexpr functions for all types for which=
T1's and
<br>> T2's operator=3D=3D are constexpr functions. Am I right?
<br>
<br>I would think you want to say that optional is literal if its underlyin=
g type is
<br>literal. We probably don't want to repeat such a generic requirement fo=
r
<br>every operation.
<br></blockquote></div></div><div><br>I want to say something more (I think=
). Being a literal type (according to my understanding) only guarantees:<br=
><ul><li>my sub-objects are literal types </li><li>I have trivial dest=
ructor</li>
<li>I have one constexpr constructor</li></ul><p></p></div></blockquote><di=
v><br>I have the same understanding.<br><br>Though I would say that this is=
effectively equivalent to what Ville said, just more formal.<br><div>
<p>
<span></span></p></div><span><font color=3D"#888888">
</font></span><br></div><blockquote class=3D"gmail_quote" style=3D"margin:0=
px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><=
div><p>In particular it does not guarantee that any observer functions are =
constexpr functions.<span><font color=3D"#888888"><br>
</font></span></p></div></blockquote><div><br>Right.<br><br>Neither that th=
e move/copy ctor is constexpr, which is why I liked option 2.<br><br></div>=
</div>>We would still have to add a requirement that instantiations of t=
his=20
templates shall render constexpr functions for all types for which <span st=
yle=3D"font-family:courier new,monospace">T1</span>'s and <span style=3D"fo=
nt-family:courier new,monospace">T2</span>'s operator=3D=3D are constexpr &=
gt;functions. Am I right?<br>
<br>I don't think so, not in the way you are saying it.<br><br>We should de=
fine certain functions (and operators, and member functions) as constexpr b=
ut that imposes no requirements in the instantiations (if the instantiation=
fails to satisfy the requirements for a constexpr then it's just not const=
expr, and the program will be ill-formed only if it the optional<> is=
attempted to be used as constant expression)<br></div></blockquote><div><b=
r>I agree with your analysis, but this means that a programmer will type th=
is code:<br><br><div class=3D"prettyprint" style=3D"background-color: rgb(2=
50, 250, 250); border-color: rgb(187, 187, 187); border-style: solid; borde=
r-width: 1px; word-wrap: break-word;"><code class=3D"prettyprint"><div clas=
s=3D"subprettyprint"><span style=3D"color: #008;" class=3D"styled-by-pretti=
fy">constexpr</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"> optional</span><span style=3D"color: #080;" class=3D"styled-by-prettify=
"><int></span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"> oi</span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</s=
pan><span style=3D"color: #066;" class=3D"styled-by-prettify">1</span><span=
style=3D"color: #660;" class=3D"styled-by-prettify">};</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"co=
lor: #008;" class=3D"styled-by-prettify">constexpr</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> optional</span><span style=3D"colo=
r: #080;" class=3D"styled-by-prettify"><int></span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> oj</span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">{</span><span style=3D"color: #066;" class=
=3D"styled-by-prettify">1</span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">};</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"><br></span><span style=3D"color: #008;" class=3D"styled-by-prettify"=
>static_assert</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">oi </=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D=3D</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"> oj</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: #0=
80;" class=3D"styled-by-prettify">"!"</span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">);</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"><br></span></div></code></div><br>And he will receive a =
compiler error saying that operator=3D=3D is not a constexpr function: it h=
as been only defined with constexpr specifier. He will accuse the standard =
library vendor that the library is not compliant with C++ Standard. But the=
vendor will say "the standard only requires that we annotate operator=3D=
=3D with constexpr; but not that these operators must be constexpr function=
s".<br> <br></div>
<p></p>
-- <br />
<br />
<br />
<br />
------=_Part_369_24118393.1353683843513--
.
Author: Fernando Cacciola <fernando.cacciola@gmail.com>
Date: Fri, 23 Nov 2012 12:22:34 -0300
Raw View
--e89a8ff1cb068f930d04cf2b2992
Content-Type: text/plain; charset=ISO-8859-1
On Fri, Nov 23, 2012 at 1:03 PM, Ville Voutilainen <
ville.voutilainen@gmail.com> wrote:
> On 23 November 2012 16:59, Fernando Cacciola
> <fernando.cacciola@gmail.com> wrote:
> > IIUC, "const" observers such as operator*, operator ==, etc... should be
> > defined with the constexpr modifier.
> > The effect is that, with optional<T> being a literal type, in the context
> > where a const optional of a literal type is used in a expression that
> calls
> > such constexpr functions, the result of the call (such as the value of
> the
> > optional or the result of a comparison) is a constant expression.
> > That is:
> > constexpr optional<int> o(123);
> > int a[ *o ] ; // This should be OK.
> > I also understand that the only requirement in terms of the std text is
> to
> > include the constexpr specifier where appropriate. I don't think any
> extra
> > clarification is needed.
>
> Ah, and if it throws an error for a disengaged optional, it's not
> constexpr, and that
> code would be ill-formed.
Right.
But it's important to empathize the "if" in your sentence.
constexpr bool foo ( int n )
{
return n == 0 ? throw : n > 0 ;
}
That definition is OK (I think there is a similar example in the std).
It is because there are values of the argument n for which the compiler
*can* apply the function call substitution, so the function definition
itself is not ill-formed
But then,
int a[ foo(2) ] ;
it's also OK because 2 is constant expression, and the definition of foo
allows the compiler to apply a function call substitution that results in (
2 == 0 ? <don't-matter> : 2 > 0 ) so the const expression corresponding to
the result of the call directly evaluates to 'true' with the other branch
being simply ignored. [as always IIUC]
OTOH,
void bar(int n )
{
int a[ foo(n) ] ;
}
is ill-formed because the argument to the function is not a constant
expression, the function call substitution results in an expression that
cannot be evaluated at compile time, and then it's not possible to ignore
the conditional branch with the throw.
But, the program becomes ill-formed at the point the function is in such a
way. The function definition is OK and allows for the first example.
--
Fernando Cacciola
SciSoft Consulting, Founder
http://www.scisoft-consulting.com
--
--e89a8ff1cb068f930d04cf2b2992
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div class=3D"gmail_extra"><br><div class=3D"gmail_quote">On Fri, Nov 23, 2=
012 at 1:03 PM, Ville Voutilainen <span dir=3D"ltr"><<a href=3D"mailto:v=
ille.voutilainen@gmail.com" target=3D"_blank">ville.voutilainen@gmail.com</=
a>></span> wrote:<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-=
left:1px solid rgb(204,204,204);padding-left:1ex">On 23 November 2012 16:59=
, Fernando Cacciola<br>
<div class=3D"im"><<a href=3D"mailto:fernando.cacciola@gmail.com">fernan=
do.cacciola@gmail.com</a>> wrote:<br>
> IIUC, =A0"const" observers such as operator*, operator =3D=
=3D, etc... should be<br>
> defined with the constexpr modifier.<br>
> The effect is that, with optional<T> being a literal type, in th=
e context<br>
> where a const optional of a literal type is used in a expression that =
calls<br>
> such constexpr functions, the result of the call (such as the value of=
the<br>
> optional or the result of a comparison) is a constant expression.<br>
> That is:<br>
> constexpr optional<int> o(123);<br>
> int a[ *o ] ; // This should be OK.<br>
> I also understand that the only requirement in terms of the std text i=
s to<br>
> include the constexpr specifier where appropriate. I don't think a=
ny extra<br>
> clarification is needed.<br>
<br>
</div>Ah, and if it throws an error for a disengaged optional, it's not=
<br>
constexpr, and that<br>
code would be ill-formed. </blockquote><div><br>Right.<br>But it's impo=
rtant to empathize the "if" in your sentence.<br><br>constexpr bo=
ol foo ( int n ) <br>{<br>=A0 return n =3D=3D 0 ? throw : n > 0 ;<br>}<b=
r>
<br>That definition is OK (I think there is a similar example in the std).<=
br>It is because there are values of the argument n for which the compiler =
*can* apply the function call substitution, so the function definition itse=
lf is not ill-formed<br>
<br>But then,<br><br>int a[ foo(2) ] ;<br><br>it's also OK because 2 is=
constant expression, and the definition of foo allows the compiler to appl=
y a function call substitution that results in ( 2 =3D=3D 0 ? <don't=
-matter> : 2 > 0 ) so the const expression corresponding to the resul=
t of the call directly evaluates to 'true' with the other branch be=
ing simply ignored. [as always IIUC]<br>
<br>OTOH,<br><br>void bar(int n )<br>{<br>=A0 int a[ foo(n) ] ;<br>}<br><br=
>is ill-formed because the argument to the function is not a constant expre=
ssion, the function call substitution results in an expression that cannot =
be evaluated at compile time, and then it's not possible to ignore the =
conditional branch with the throw.<br>
<br>But, the program becomes ill-formed at the point the function is in suc=
h a way. The function definition is OK and allows for the first example.<br=
>=A0<br></div></div><br><br clear=3D"all"><br>-- <br>Fernando Cacciola<br>
SciSoft Consulting, Founder<br>
<a href=3D"http://www.scisoft-consulting.com">http://www.scisoft-consulting=
..com</a><br>
</div>
<p></p>
-- <br />
<br />
<br />
<br />
--e89a8ff1cb068f930d04cf2b2992--
.
Author: Fernando Cacciola <fernando.cacciola@gmail.com>
Date: Fri, 23 Nov 2012 12:28:22 -0300
Raw View
--e89a8f8396e351e74104cf2b3e69
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Fri, Nov 23, 2012 at 1:17 PM, Andrzej Krzemie=C5=84ski <akrzemi1@gmail.c=
om>wrote:
>
>
> constexpr optional<int> oi{1};
> constexpr optional<int> oj{1};
> static_assert(oi =3D=3D oj, "!");
>
> And he will receive a compiler error saying that operator=3D=3D is not a
> constexpr function: it has been only defined with constexpr specifier. He
> will accuse the standard library vendor that the library is not compliant
> with C++ Standard. But the vendor will say "the standard only requires th=
at
> we annotate operator=3D=3D with constexpr; but not that these operators m=
ust be
> constexpr functions".
>
>
Then I'm missing something (and if I am, something IS missing :)
How does including the constexpr specifier in the definition of the
template function operator=3D=3D fails to "make it a constexpr function"?
Or else, how do you make such a thing other than by including the constexpr
specifier in the definition (or declaration but it doesn't matter to this
argument)?
Or are are you saying that we put that in the proposal, then the std text
includes something like:
constexpr bool operator =3D=3D ( bla bla )
BUT then a library implementer drops the constexpr?
That's not possible. Such an implementation would be non-conforming.
Best
--=20
Fernando Cacciola
SciSoft Consulting, Founder
http://www.scisoft-consulting.com
--=20
--e89a8f8396e351e74104cf2b3e69
Content-Type: text/html; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable
<br><div class=3D"gmail_extra"><div class=3D"gmail_quote">On Fri, Nov 23, 2=
012 at 1:17 PM, Andrzej Krzemie=F1ski <span dir=3D"ltr"><<a href=3D"mail=
to:akrzemi1@gmail.com" target=3D"_blank">akrzemi1@gmail.com</a>></span> =
wrote:<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><br><div><br><div style=3D"background-color:=
rgb(250,250,250);border-color:rgb(187,187,187);border-style:solid;border-wi=
dth:1px;word-wrap:break-word">
<code><div><span style=3D"color:#008">constexpr</span><span style> optional=
</span><span style=3D"color:#080"><int></span><span style> oi</span><=
span style=3D"color:#660">{</span><span style=3D"color:#066">1</span><span =
style=3D"color:#660">};</span><span style><br>
</span><span style=3D"color:#008">constexpr</span><span style> optional</sp=
an><span style=3D"color:#080"><int></span><span style> oj</span><span=
style=3D"color:#660">{</span><span style=3D"color:#066">1</span><span styl=
e=3D"color:#660">};</span><span style><br>
</span><span style=3D"color:#008">static_assert</span><span style=3D"color:=
#660">(</span><span style>oi </span><span style=3D"color:#660">=3D=3D</span=
><span style> oj</span><span style=3D"color:#660">,</span><span style> </sp=
an><span style=3D"color:#080">"!"</span><span style=3D"color:#660=
">);</span><span style><br>
</span></div></code></div><br>And he will receive a compiler error saying t=
hat operator=3D=3D is not a constexpr function: it has been only defined wi=
th constexpr specifier. He will accuse the standard library vendor that the=
library is not compliant with C++ Standard. But the vendor will say "=
the standard only requires that we annotate operator=3D=3D with constexpr; =
but not that these operators must be constexpr functions".<span class=
=3D"HOEnZb"><font color=3D"#888888"><br>
=A0 <br></font></span></div></blockquote><div><br>Then I'm missing some=
thing (and if I am, something IS missing :)<br>=A0<br>How does including th=
e constexpr specifier in the definition of the template function operator=
=3D=3D fails to "make it a constexpr function"?<br>
<br>Or else, how do you make such a thing other than by including the const=
expr specifier in the definition (or declaration but it doesn't matter =
to this argument)?<br><br>Or are are you saying that we put that in the pro=
posal, then the std text includes something like:<br>
<br>constexpr bool operator =3D=3D ( bla bla )<br><br>BUT then a library im=
plementer drops the constexpr?<br><br>That's not possible. Such an impl=
ementation would be non-conforming.<br><br>Best<br></div></div><br clear=3D=
"all">
<br>-- <br>Fernando Cacciola<br>SciSoft Consulting, Founder<br><a href=3D"h=
ttp://www.scisoft-consulting.com">http://www.scisoft-consulting.com</a><br>
</div>
<p></p>
-- <br />
<br />
<br />
<br />
--e89a8f8396e351e74104cf2b3e69--
.
Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Fri, 23 Nov 2012 17:34:13 +0200
Raw View
On 23 November 2012 17:28, Fernando Cacciola
<fernando.cacciola@gmail.com> wrote:
> Then I'm missing something (and if I am, something IS missing :)
> How does including the constexpr specifier in the definition of the template
> function operator== fails to "make it a constexpr function"?
Not all instantiations of a function template marked constexpr need to
be constexpr.
What Andrzej is saying is that he wants to specify the circumstances under which
the instantiations are constexpr, rather than leave all that to the
implementation's discretion.
And I understand that point, now that I've thought of it.
--
.
Author: Fernando Cacciola <fernando.cacciola@gmail.com>
Date: Fri, 23 Nov 2012 12:52:58 -0300
Raw View
--f46d044517a34009bb04cf2b9631
Content-Type: text/plain; charset=ISO-8859-1
On Fri, Nov 23, 2012 at 12:34 PM, Ville Voutilainen <
ville.voutilainen@gmail.com> wrote:
> On 23 November 2012 17:28, Fernando Cacciola
> <fernando.cacciola@gmail.com> wrote:
> > Then I'm missing something (and if I am, something IS missing :)
> > How does including the constexpr specifier in the definition of the
> template
> > function operator== fails to "make it a constexpr function"?
>
> Not all instantiations of a function template marked constexpr need to
> be constexpr.
>
Right.
Just like not all calls to a constexpr functions are constant expressions.
What Andrzej is saying is that he wants to specify the circumstances under
> which
> the instantiations are constexpr, rather than leave all that to the
> implementation's discretion.
> And I understand that point, now that I've thought of it.
>
>
Oh... is it Andrzej?
If so, I don't think we should do that.
All the library classes that are also literal types (take pair<> as the
closest example) just contain constexpr where needed without any additional
clarification.
In fact, numeric_limits its the exception for it says as the beginning:
"For all members declared static constexpr in the numeric_limits template,
specializations shall define
these values in such a way that they are usable as constant expressions."
which can be regarded as unnecessary.
IMO, clause 7.1.5 where the semantics of the constexpr modifier are
specified is sufficient to establish what implementations should do with
constexpr functions
Also, for an optional<T> implementation, and because we decided on option
2, I would expect any implementation to do the trivially right thing (and
we'll provide a reference implementation just in case that is not as
evident as I think it is)
Best
--
Fernando Cacciola
SciSoft Consulting, Founder
http://www.scisoft-consulting.com
--
--f46d044517a34009bb04cf2b9631
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div class=3D"gmail_extra"><div class=3D"gmail_quote">On Fri, Nov 23, 2012 =
at 12:34 PM, Ville Voutilainen <span dir=3D"ltr"><<a href=3D"mailto:vill=
e.voutilainen@gmail.com" target=3D"_blank">ville.voutilainen@gmail.com</a>&=
gt;</span> wrote:<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-=
left:1px solid rgb(204,204,204);padding-left:1ex">On 23 November 2012 17:28=
, Fernando Cacciola<br>
<div class=3D"im"><<a href=3D"mailto:fernando.cacciola@gmail.com">fernan=
do.cacciola@gmail.com</a>> wrote:<br>
> Then I'm missing something (and if I am, something IS missing :)<b=
r>
> How does including the constexpr specifier in the definition of the te=
mplate<br>
> function operator=3D=3D fails to "make it a constexpr function&qu=
ot;?<br>
<br>
</div>Not all instantiations of a function template marked constexpr need t=
o<br>
be constexpr.<br></blockquote><div><br>Right.<br>Just like not all calls to=
a constexpr functions are constant expressions.<br><br><br><br></div><bloc=
kquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:=
1px solid rgb(204,204,204);padding-left:1ex">
What Andrzej is saying is that he wants to specify the circumstances under =
which<br>
the instantiations are constexpr, rather than leave all that to the<br>
implementation's discretion.<br>
And I understand that point, now that I've thought of it.<br>
<span class=3D""><font color=3D"#888888"><br></font></span></blockquote><di=
v><br>Oh... is it Andrzej?<br><br>If so, I don't think we should do tha=
t.<br><br>All the library classes that are also literal types (take pair<=
;> as the closest example) just contain constexpr where needed without a=
ny additional clarification.<br>
In fact, numeric_limits its the exception for it says as the beginning:<br>=
<br>"For all members declared static constexpr in the numeric_limits t=
emplate, specializations shall define<br>these values in such a way that th=
ey are usable as constant expressions."<br>
<br>which can be regarded as unnecessary.<br><br>IMO, clause 7.1.5 where th=
e semantics of the constexpr modifier are specified is sufficient to establ=
ish what implementations should do with constexpr functions<br><br>Also, fo=
r an optional<T> implementation, and because we decided on option 2, =
I would expect any implementation to do the trivially right thing (and we&#=
39;ll provide a reference implementation just in case that is not as eviden=
t as I think it is)<br>
<br><br>Best<br><br></div></div><br clear=3D"all"><br>-- <br>Fernando Cacci=
ola<br>SciSoft Consulting, Founder<br><a href=3D"http://www.scisoft-consult=
ing.com">http://www.scisoft-consulting.com</a><br>
</div>
<p></p>
-- <br />
<br />
<br />
<br />
--f46d044517a34009bb04cf2b9631--
.
Author: =?UTF-8?Q?Andrzej_Krzemie=C5=84ski?= <akrzemi1@gmail.com>
Date: Fri, 23 Nov 2012 07:54:38 -0800 (PST)
Raw View
------=_Part_1025_1709176.1353686078403
Content-Type: text/plain; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable
W dniu pi=B1tek, 23 listopada 2012 16:29:04 UTC+1 u=BFytkownik Fernando=20
Cacciola napisa=B3:
>
>
> On Fri, Nov 23, 2012 at 1:17 PM, Andrzej Krzemie=F1ski <akrz...@gmail.com=
<javascript:>
> > wrote:
>
>>
>>
>> constexpr optional<int> oi{1};
>> constexpr optional<int> oj{1};
>> static_assert(oi =3D=3D oj, "!");
>>
>> And he will receive a compiler error saying that operator=3D=3D is not a=
=20
>> constexpr function: it has been only defined with constexpr specifier. H=
e=20
>> will accuse the standard library vendor that the library is not complian=
t=20
>> with C++ Standard. But the vendor will say "the standard only requires t=
hat=20
>> we annotate operator=3D=3D with constexpr; but not that these operators =
must be=20
>> constexpr functions".
>> =20
>>
>
> Then I'm missing something (and if I am, something IS missing :)
> =20
> How does including the constexpr specifier in the definition of the=20
> template function operator=3D=3D fails to "make it a constexpr function"?
>
> Or else, how do you make such a thing other than by including the=20
> constexpr specifier in the definition (or declaration but it doesn't matt=
er=20
> to this argument)?
>
> Or are are you saying that we put that in the proposal, then the std text=
=20
> includes something like:
>
> constexpr bool operator =3D=3D ( bla bla )
>
> BUT then a library implementer drops the constexpr?
>
> That's not possible. Such an implementation would be non-conforming.
>
Let me illustrate this with an example:
struct Trash{}; // just a dummy tag=20
constexpr Trash trash{}; //
constexpr bool equal_impl(Trash const&, Trash const&)=20
{=20
return true;=20
}
template <class T> // no constexpr
bool equal_impl(T const& x, T const& y)=20
{=20
doSomethingAtRuntime();
return x =3D=3D y;
}
template <class T>
constexpr bool equal(T const& x, T const& y)=20
{=20
return equal_impl(x, y);=20
}
You can legally define constexpr function equal like the above, even though=
=20
no instantiation (except for a single one for type Trash) renders a=20
constexpr function.=20
This is allowed by (7.1.5 para 6):=20
If the instantiated template specialization of a constexpr function=20
template or member function of a class
template would fail to satisfy the requirements for a constexpr function or=
=20
constexpr constructor, that
specialization is not a constexpr function or constexpr constructor. [...]=
=20
If no specialization of the template would
yield a constexpr function or constexpr constructor, the program is=20
ill-formed; no diagnostic required.
--=20
------=_Part_1025_1709176.1353686078403
Content-Type: text/html; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable
<br><br>W dniu pi=B1tek, 23 listopada 2012 16:29:04 UTC+1 u=BFytkownik Fern=
ando Cacciola napisa=B3:<blockquote class=3D"gmail_quote" style=3D"margin: =
0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><br><d=
iv><div class=3D"gmail_quote">On Fri, Nov 23, 2012 at 1:17 PM, Andrzej Krze=
mie=F1ski <span dir=3D"ltr"><<a href=3D"javascript:" target=3D"_blank" g=
df-obfuscated-mailto=3D"NVgL509T7woJ">akrz...@gmail.com</a>></span> wrot=
e:<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><br><div><br><div style=3D"background-color:=
rgb(250,250,250);border-color:rgb(187,187,187);border-style:solid;border-wi=
dth:1px;word-wrap:break-word">
<code><div><span style=3D"color:#008">constexpr</span><span> optional</span=
><span style=3D"color:#080"><int></span><span> oi</span><span style=
=3D"color:#660">{</span><span style=3D"color:#066">1</span><span style=3D"c=
olor:#660">};</span><span><br>
</span><span style=3D"color:#008">constexpr</span><span> optional</span><sp=
an style=3D"color:#080"><int></span><span> oj</span><span style=3D"co=
lor:#660">{</span><span style=3D"color:#066">1</span><span style=3D"color:#=
660">};</span><span><br>
</span><span style=3D"color:#008">static_assert</span><span style=3D"color:=
#660">(</span><span>oi </span><span style=3D"color:#660">=3D=3D</span><span=
> oj</span><span style=3D"color:#660">,</span><span> </span><span style=3D"=
color:#080">"!"</span><span style=3D"color:#660">);</span><span><br>
</span></div></code></div><br>And he will receive a compiler error saying t=
hat operator=3D=3D is not a constexpr function: it has been only defined wi=
th constexpr specifier. He will accuse the standard library vendor that the=
library is not compliant with C++ Standard. But the vendor will say "the s=
tandard only requires that we annotate operator=3D=3D with constexpr; but n=
ot that these operators must be constexpr functions".<span><font color=3D"#=
888888"><br>
<br></font></span></div></blockquote><div><br>Then I'm missing somet=
hing (and if I am, something IS missing :)<br> <br>How does including =
the constexpr specifier in the definition of the template function operator=
=3D=3D fails to "make it a constexpr function"?<br>
<br>Or else, how do you make such a thing other than by including the const=
expr specifier in the definition (or declaration but it doesn't matter to t=
his argument)?<br><br>Or are are you saying that we put that in the proposa=
l, then the std text includes something like:<br>
<br>constexpr bool operator =3D=3D ( bla bla )<br><br>BUT then a library im=
plementer drops the constexpr?<br><br>That's not possible. Such an implemen=
tation would be non-conforming.<br></div></div></div></blockquote><div><br>=
Let me illustrate this with an example:<br><div class=3D"prettyprint" style=
=3D"background-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187);=
border-style: solid; border-width: 1px; word-wrap: break-word;"><code clas=
s=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"color: #008;=
" class=3D"styled-by-prettify">struct</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"> </span><span style=3D"color: #606;" class=3D"st=
yled-by-prettify">Trash</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: #800=
;" class=3D"styled-by-prettify">// just a dummy tag </span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: =
#008;" class=3D"styled-by-prettify">constexpr</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #606;" cla=
ss=3D"styled-by-prettify">Trash</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"> trash</span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">{};</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> </span><span style=3D"color: #800;" class=3D"styled-by-pre=
ttify">//</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><=
br><br></span><span style=3D"color: #008;" class=3D"styled-by-prettify">con=
stexpr</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </s=
pan><span style=3D"color: #008;" class=3D"styled-by-prettify">bool</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> equal_impl</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span styl=
e=3D"color: #606;" class=3D"styled-by-prettify">Trash</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #0=
08;" class=3D"styled-by-prettify">const</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">&,</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"> </span><span style=3D"color: #606;" class=3D"styl=
ed-by-prettify">Trash</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify=
">const</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&am=
p;)</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> <br></=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> <br> </span><s=
pan style=3D"color: #008;" class=3D"styled-by-prettify">return</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"=
color: #008;" class=3D"styled-by-prettify">true</span><span style=3D"color:=
#660;" class=3D"styled-by-prettify">;</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> <br></span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">}</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"><br><br></span><span style=3D"color: #008;" class=3D"styled-=
by-prettify">template</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: #008;" class=3D"styled-by-prettify">clas=
s</span><span 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"> &=
nbsp;</span><span style=3D"color: #800;" class=3D"styled-by-prettify">// no=
constexpr</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
<br></span><span style=3D"color: #008;" class=3D"styled-by-prettify">bool</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> equal_impl<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify">T </span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">const</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">&</span><span style=3D"color:=
#000;" class=3D"styled-by-prettify"> x</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: #008;" class=3D"styled-=
by-prettify">const</span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">&</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"> y</span><span style=3D"color: #660;" class=3D"styled-by-prettify">)</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> <br></span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> <br> doSomethingAtRun=
time</span><span style=3D"color: #660;" class=3D"styled-by-prettify">();</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"><br> </=
span><span style=3D"color: #008;" class=3D"styled-by-prettify">return</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"> x </span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">=3D=3D</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"> y</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">;</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"><br></span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">}</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"><br><br></span><span style=3D"color: #008;" class=3D"styled=
-by-prettify">template</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y"><</span><span style=3D"color: #008;" class=3D"styled-by-prettify">cla=
ss</span><span 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"><br></span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">constexpr</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #008;" class=3D"styled-by-prettify">bool</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify"> equal</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify">T </span><span style=3D"color: #008;" class=3D"styled-by=
-prettify">const</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">&</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> x</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: #008;" class=3D"styled-by-prettify">const</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">&</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> y</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">)</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"> <br></span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"> <br> </span><span style=3D"color: #008;" class=3D"styled-=
by-prettify">return</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> equal_impl</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
>x</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> y</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">);</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> <br></span><span style=3D"color:=
#660;" class=3D"styled-by-prettify">}</span></div></code></div><br>You can=
legally define constexpr function <span style=3D"font-family: courier new,=
monospace;">equal </span>like the above, even though no instantiation (exce=
pt for a single one for type <span style=3D"font-family: courier new,monosp=
ace;">Trash</span>) renders a constexpr function. <br><br>This is allowed b=
y (7.1.5 para 6): <br><div style=3D"margin-left: 40px;">If the instantiated=
template specialization of a constexpr function template or member functio=
n of a class<br>template would fail to satisfy the requirements for a const=
expr function or constexpr constructor, that<br>specialization is not a con=
stexpr function or constexpr constructor. [...] If no specialization of the=
template would<br>yield a constexpr function or constexpr constructor, the=
program is ill-formed; no diagnostic required.<br></div></div>
<p></p>
-- <br />
<br />
<br />
<br />
------=_Part_1025_1709176.1353686078403--
.
Author: Fernando Cacciola <fernando.cacciola@gmail.com>
Date: Fri, 23 Nov 2012 13:00:00 -0300
Raw View
--f46d0444e8697cb57d04cf2baf81
Content-Type: text/plain; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable
You lost me :)
I agree that you example is valid.
A call to equal(2,2) would not be a const expression because it would fall
to the non-constexpr impl.
A call to equal(trash,trash) OTOH will be.
Now, what's the problem here? What would you like to improve? and most
importantly, how does any of this relate to optional<>? :)
On Fri, Nov 23, 2012 at 12:54 PM, Andrzej Krzemie=F1ski <akrzemi1@gmail.com=
>wrote:
>
>
> W dniu pi=B1tek, 23 listopada 2012 16:29:04 UTC+1 u=BFytkownik Fernando
> Cacciola napisa=B3:
>
>>
>> On Fri, Nov 23, 2012 at 1:17 PM, Andrzej Krzemie=F1ski <akrz...@gmail.co=
m>wrote:
>>
>>>
>>>
>>> constexpr optional<int> oi{1};
>>> constexpr optional<int> oj{1};
>>> static_assert(oi =3D=3D oj, "!");
>>>
>>> And he will receive a compiler error saying that operator=3D=3D is not =
a
>>> constexpr function: it has been only defined with constexpr specifier. =
He
>>> will accuse the standard library vendor that the library is not complia=
nt
>>> with C++ Standard. But the vendor will say "the standard only requires =
that
>>> we annotate operator=3D=3D with constexpr; but not that these operators=
must be
>>> constexpr functions".
>>>
>>>
>>
>> Then I'm missing something (and if I am, something IS missing :)
>>
>> How does including the constexpr specifier in the definition of the
>> template function operator=3D=3D fails to "make it a constexpr function"=
?
>>
>> Or else, how do you make such a thing other than by including the
>> constexpr specifier in the definition (or declaration but it doesn't mat=
ter
>> to this argument)?
>>
>> Or are are you saying that we put that in the proposal, then the std tex=
t
>> includes something like:
>>
>> constexpr bool operator =3D=3D ( bla bla )
>>
>> BUT then a library implementer drops the constexpr?
>>
>> That's not possible. Such an implementation would be non-conforming.
>>
>
> Let me illustrate this with an example:
> struct Trash{}; // just a dummy tag
> constexpr Trash trash{}; //
>
> constexpr bool equal_impl(Trash const&, Trash const&)
> {
> return true;
> }
>
> template <class T> // no constexpr
> bool equal_impl(T const& x, T const& y)
> {
> doSomethingAtRuntime();
> return x =3D=3D y;
> }
>
> template <class T>
> constexpr bool equal(T const& x, T const& y)
> {
> return equal_impl(x, y);
> }
>
> You can legally define constexpr function equal like the above, even
> though no instantiation (except for a single one for type Trash) renders
> a constexpr function.
>
> This is allowed by (7.1.5 para 6):
> If the instantiated template specialization of a constexpr function
> template or member function of a class
> template would fail to satisfy the requirements for a constexpr function
> or constexpr constructor, that
> specialization is not a constexpr function or constexpr constructor. [...=
]
> If no specialization of the template would
> yield a constexpr function or constexpr constructor, the program is
> ill-formed; no diagnostic required.
>
> --
>
>
>
>
--=20
Fernando Cacciola
SciSoft Consulting, Founder
http://www.scisoft-consulting.com
--=20
--f46d0444e8697cb57d04cf2baf81
Content-Type: text/html; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable
You lost me :)<br><br>I agree that you example is valid.<br><br>A call to e=
qual(2,2) would not be a const expression because it would fall to the non-=
constexpr impl.<br>A call to equal(trash,trash) OTOH will be.<br><br>Now, w=
hat's the problem here? What would you like to improve? and most import=
antly, how does any of this relate to optional<>? :)<br>
<br><br><div class=3D"gmail_extra"><br><br><div class=3D"gmail_quote">On Fr=
i, Nov 23, 2012 at 12:54 PM, Andrzej Krzemie=F1ski <span dir=3D"ltr"><<a=
href=3D"mailto:akrzemi1@gmail.com" target=3D"_blank">akrzemi1@gmail.com</a=
>></span> wrote:<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><br><br>W dniu pi=B1tek, 23 listopada 2012 1=
6:29:04 UTC+1 u=BFytkownik Fernando Cacciola napisa=B3:<div class=3D"im"><b=
lockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-=
left:1px #ccc solid;padding-left:1ex">
<br><div><div class=3D"gmail_quote">On Fri, Nov 23, 2012 at 1:17 PM, Andrze=
j Krzemie=F1ski <span dir=3D"ltr"><<a>akrz...@gmail.com</a>></span> w=
rote:<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><br><div><br><div style=3D"background-color:=
rgb(250,250,250);border-color:rgb(187,187,187);border-style:solid;border-wi=
dth:1px;word-wrap:break-word">
<code><div><span style=3D"color:#008">constexpr</span><span> optional</span=
><span style=3D"color:#080"><int></span><span> oi</span><span style=
=3D"color:#660">{</span><span style=3D"color:#066">1</span><span style=3D"c=
olor:#660">};</span><span><br>
</span><span style=3D"color:#008">constexpr</span><span> optional</span><sp=
an style=3D"color:#080"><int></span><span> oj</span><span style=3D"co=
lor:#660">{</span><span style=3D"color:#066">1</span><span style=3D"color:#=
660">};</span><span><br>
</span><span style=3D"color:#008">static_assert</span><span style=3D"color:=
#660">(</span><span>oi </span><span style=3D"color:#660">=3D=3D</span><span=
> oj</span><span style=3D"color:#660">,</span><span> </span><span style=3D"=
color:#080">"!"</span><span style=3D"color:#660">);</span><span><=
br>
</span></div></code></div><br>And he will receive a compiler error saying t=
hat operator=3D=3D is not a constexpr function: it has been only defined wi=
th constexpr specifier. He will accuse the standard library vendor that the=
library is not compliant with C++ Standard. But the vendor will say "=
the standard only requires that we annotate operator=3D=3D with constexpr; =
but not that these operators must be constexpr functions".<span><font =
color=3D"#888888"><br>
=A0 <br></font></span></div></blockquote><div><br>Then I'm missing some=
thing (and if I am, something IS missing :)<br>=A0<br>How does including th=
e constexpr specifier in the definition of the template function operator=
=3D=3D fails to "make it a constexpr function"?<br>
<br>Or else, how do you make such a thing other than by including the const=
expr specifier in the definition (or declaration but it doesn't matter =
to this argument)?<br><br>Or are are you saying that we put that in the pro=
posal, then the std text includes something like:<br>
<br>constexpr bool operator =3D=3D ( bla bla )<br><br>BUT then a library im=
plementer drops the constexpr?<br><br>That's not possible. Such an impl=
ementation would be non-conforming.<br></div></div></div></blockquote></div=
>
<div><br>Let me illustrate this with an example:<br><div style=3D"backgroun=
d-color:rgb(250,250,250);border-color:rgb(187,187,187);border-style:solid;b=
order-width:1px;word-wrap:break-word"><code><div><span style=3D"color:#008"=
>struct</span><span style> </span><span style=3D"color:#606">Trash</span><s=
pan style=3D"color:#660">{};</span><span style> =A0 =A0 =A0 =A0 =A0 </span>=
<span style=3D"color:#800">// just a dummy tag </span><span style><br>
</span><span style=3D"color:#008">constexpr</span><span style> </span><span=
style=3D"color:#606">Trash</span><span style> trash</span><span style=3D"c=
olor:#660">{};</span><span style> =A0</span><span style=3D"color:#800">//</=
span><span style><br>
<br></span><span style=3D"color:#008">constexpr</span><span style> </span><=
span style=3D"color:#008">bool</span><span style> equal_impl</span><span st=
yle=3D"color:#660">(</span><span style=3D"color:#606">Trash</span><span sty=
le> </span><span style=3D"color:#008">const</span><span style=3D"color:#660=
">&,</span><span style> </span><span style=3D"color:#606">Trash</span><=
span style> </span><span style=3D"color:#008">const</span><span style=3D"co=
lor:#660">&)</span><span style> <br>
</span><span style=3D"color:#660">{</span><span style> <br>=A0 </span><span=
style=3D"color:#008">return</span><span style> </span><span style=3D"color=
:#008">true</span><span style=3D"color:#660">;</span><span style> <br></spa=
n><span style=3D"color:#660">}</span><span style><br>
<br></span><span style=3D"color:#008">template</span><span style> </span><s=
pan style=3D"color:#660"><</span><span style=3D"color:#008">class</span>=
<span style> T</span><span style=3D"color:#660">></span><span style> =A0=
=A0 =A0 =A0</span><span style=3D"color:#800">// no constexpr</span><span s=
tyle><br>
</span><span style=3D"color:#008">bool</span><span style> equal_impl</span>=
<span style=3D"color:#660">(</span><span style>T </span><span style=3D"colo=
r:#008">const</span><span style=3D"color:#660">&</span><span style> x</=
span><span style=3D"color:#660">,</span><span style> T </span><span style=
=3D"color:#008">const</span><span style=3D"color:#660">&</span><span st=
yle> y</span><span style=3D"color:#660">)</span><span style> <br>
</span><span style=3D"color:#660">{</span><span style> <br>=A0 doSomethingA=
tRuntime</span><span style=3D"color:#660">();</span><span style><br>=A0 </s=
pan><span style=3D"color:#008">return</span><span style> x </span><span sty=
le=3D"color:#660">=3D=3D</span><span style> y</span><span style=3D"color:#6=
60">;</span><span style><br>
</span><span style=3D"color:#660">}</span><span style><br><br></span><span =
style=3D"color:#008">template</span><span style> </span><span style=3D"colo=
r:#660"><</span><span style=3D"color:#008">class</span><span style> T</s=
pan><span style=3D"color:#660">></span><span style><br>
</span><span style=3D"color:#008">constexpr</span><span style> </span><span=
style=3D"color:#008">bool</span><span style> equal</span><span style=3D"co=
lor:#660">(</span><span style>T </span><span style=3D"color:#008">const</sp=
an><span style=3D"color:#660">&</span><span style> x</span><span style=
=3D"color:#660">,</span><span style> T </span><span style=3D"color:#008">co=
nst</span><span style=3D"color:#660">&</span><span style> y</span><span=
style=3D"color:#660">)</span><span style> <br>
</span><span style=3D"color:#660">{</span><span style> <br>=A0 </span><span=
style=3D"color:#008">return</span><span style> equal_impl</span><span styl=
e=3D"color:#660">(</span><span style>x</span><span style=3D"color:#660">,</=
span><span style> y</span><span style=3D"color:#660">);</span><span style> =
<br>
</span><span style=3D"color:#660">}</span></div></code></div><br>You can le=
gally define constexpr function <span style=3D"font-family:courier new,mono=
space">equal </span>like the above, even though no instantiation (except fo=
r a single one for type <span style=3D"font-family:courier new,monospace">T=
rash</span>) renders a constexpr function. <br>
<br>This is allowed by (7.1.5 para 6): <br><div style=3D"margin-left:40px">=
If the instantiated template specialization of a constexpr function templat=
e or member function of a class<br>template would fail to satisfy the requi=
rements for a constexpr function or constexpr constructor, that<br>
specialization is not a constexpr function or constexpr constructor. [...] =
If no specialization of the template would<br>yield a constexpr function or=
constexpr constructor, the program is ill-formed; no diagnostic required.<=
span class=3D"HOEnZb"><font color=3D"#888888"><br>
</font></span></div></div><span class=3D"HOEnZb"><font color=3D"#888888">
<p></p>
-- <br>
=A0<br>
=A0<br>
=A0<br>
</font></span></blockquote></div><br><br clear=3D"all"><br>-- <br>Fernando =
Cacciola<br>SciSoft Consulting, Founder<br><a href=3D"http://www.scisoft-co=
nsulting.com">http://www.scisoft-consulting.com</a><br>
</div>
<p></p>
-- <br />
<br />
<br />
<br />
--f46d0444e8697cb57d04cf2baf81--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Fri, 23 Nov 2012 08:50:54 -0800 (PST)
Raw View
------=_Part_1087_24777331.1353689454804
Content-Type: text/plain; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable
On Friday, November 23, 2012 8:00:42 AM UTC-8, Fernando Cacciola wrote:
>
> You lost me :)
>
> I agree that you example is valid.
>
> A call to equal(2,2) would not be a const expression because it would fal=
l=20
> to the non-constexpr impl.
> A call to equal(trash,trash) OTOH will be.
>
> Now, what's the problem here? What would you like to improve? and most=20
> importantly, how does any of this relate to optional<>? :)
>
He wants the standard itself to *guarantee* what will and will not be a=20
true constexpr. He wants the standard to provide guarantees about the usage=
=20
of these observers that will *force* all conforming implementations to all=
=20
be constexpr in the same way.
All the standard would say about something like `equal` is that it is=20
declared `constexpr`. That means nothing about the circumstances under=20
which a particular implementation is actually a constant expression. He=20
wants the standard to provide more information about when uses of optional=
=20
will be constant expressions and when they will not.
=20
>
>
>
>
> On Fri, Nov 23, 2012 at 12:54 PM, Andrzej Krzemie=F1ski <akrz...@gmail.co=
m<javascript:>
> > wrote:
>
>>
>>
>> W dniu pi=B1tek, 23 listopada 2012 16:29:04 UTC+1 u=BFytkownik Fernando=
=20
>> Cacciola napisa=B3:
>>
>>>
>>> On Fri, Nov 23, 2012 at 1:17 PM, Andrzej Krzemie=F1ski <akrz...@gmail.c=
om>wrote:
>>>
>>>>
>>>>
>>>> constexpr optional<int> oi{1};
>>>> constexpr optional<int> oj{1};
>>>> static_assert(oi =3D=3D oj, "!");
>>>>
>>>> And he will receive a compiler error saying that operator=3D=3D is not=
a=20
>>>> constexpr function: it has been only defined with constexpr specifier.=
He=20
>>>> will accuse the standard library vendor that the library is not compli=
ant=20
>>>> with C++ Standard. But the vendor will say "the standard only requires=
that=20
>>>> we annotate operator=3D=3D with constexpr; but not that these operator=
s must be=20
>>>> constexpr functions".
>>>> =20
>>>>
>>>
>>> Then I'm missing something (and if I am, something IS missing :)
>>> =20
>>> How does including the constexpr specifier in the definition of the=20
>>> template function operator=3D=3D fails to "make it a constexpr function=
"?
>>>
>>> Or else, how do you make such a thing other than by including the=20
>>> constexpr specifier in the definition (or declaration but it doesn't ma=
tter=20
>>> to this argument)?
>>>
>>> Or are are you saying that we put that in the proposal, then the std=20
>>> text includes something like:
>>>
>>> constexpr bool operator =3D=3D ( bla bla )
>>>
>>> BUT then a library implementer drops the constexpr?
>>>
>>> That's not possible. Such an implementation would be non-conforming.
>>>
>>
>> Let me illustrate this with an example:
>> struct Trash{}; // just a dummy tag=20
>> constexpr Trash trash{}; //
>>
>> constexpr bool equal_impl(Trash const&, Trash const&)=20
>> {=20
>> return true;=20
>> }
>>
>> template <class T> // no constexpr
>> bool equal_impl(T const& x, T const& y)=20
>> {=20
>> doSomethingAtRuntime();
>> return x =3D=3D y;
>> }
>>
>> template <class T>
>> constexpr bool equal(T const& x, T const& y)=20
>> {=20
>> return equal_impl(x, y);=20
>> }
>>
>> You can legally define constexpr function equal like the above, even=20
>> though no instantiation (except for a single one for type Trash) renders=
=20
>> a constexpr function.=20
>>
>> This is allowed by (7.1.5 para 6):=20
>> If the instantiated template specialization of a constexpr function=20
>> template or member function of a class
>> template would fail to satisfy the requirements for a constexpr function=
=20
>> or constexpr constructor, that
>> specialization is not a constexpr function or constexpr constructor.=20
>> [...] If no specialization of the template would
>> yield a constexpr function or constexpr constructor, the program is=20
>> ill-formed; no diagnostic required.
>> =20
>> --=20
>> =20
>> =20
>> =20
>>
>
>
>
> --=20
> Fernando Cacciola
> SciSoft Consulting, Founder
> http://www.scisoft-consulting.com
> =20
--=20
------=_Part_1087_24777331.1353689454804
Content-Type: text/html; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable
<br><br>On Friday, November 23, 2012 8:00:42 AM UTC-8, Fernando Cacciola wr=
ote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex=
;border-left: 1px #ccc solid;padding-left: 1ex;">You lost me :)<br><br>I ag=
ree that you example is valid.<br><br>A call to equal(2,2) would not be a c=
onst expression because it would fall to the non-constexpr impl.<br>A call =
to equal(trash,trash) OTOH will be.<br><br>Now, what's the problem here? Wh=
at would you like to improve? and most importantly, how does any of this re=
late to optional<>? :)<br></blockquote><div><br>He wants the standard=
itself to <i>guarantee</i> what will and will not be a true constexpr. He =
wants the standard to provide guarantees about the usage of these observers=
that will <i>force</i> all conforming implementations to all be constexpr =
in the same way.<br><br>All the standard would say about something like `eq=
ual` is that it is declared `constexpr`. That means nothing about the circu=
mstances under which a particular implementation is actually a constant exp=
ression. He wants the standard to provide more information about when uses =
of optional will be constant expressions and when they will not.<br> <=
/div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8e=
x;border-left: 1px #ccc solid;padding-left: 1ex;">
<br><br><div><br><br><div class=3D"gmail_quote">On Fri, Nov 23, 2012 at 12:=
54 PM, Andrzej Krzemie=F1ski <span dir=3D"ltr"><<a href=3D"javascript:" =
target=3D"_blank" gdf-obfuscated-mailto=3D"lXy7ib0yi8wJ">akrz...@gmail.com<=
/a>></span> wrote:<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><br><br>W dniu pi=B1tek, 23 listopada 2012 1=
6:29:04 UTC+1 u=BFytkownik Fernando Cacciola napisa=B3:<div><blockquote cla=
ss=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc=
solid;padding-left:1ex">
<br><div><div class=3D"gmail_quote">On Fri, Nov 23, 2012 at 1:17 PM, Andrze=
j Krzemie=F1ski <span dir=3D"ltr"><<a>akrz...@gmail.com</a>></span> w=
rote:<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><br><div><br><div style=3D"background-color:=
rgb(250,250,250);border-color:rgb(187,187,187);border-style:solid;border-wi=
dth:1px;word-wrap:break-word">
<code><div><span style=3D"color:#008">constexpr</span><span> optional</span=
><span style=3D"color:#080"><int></span><span> oi</span><span style=
=3D"color:#660">{</span><span style=3D"color:#066">1</span><span style=3D"c=
olor:#660">};</span><span><br>
</span><span style=3D"color:#008">constexpr</span><span> optional</span><sp=
an style=3D"color:#080"><int></span><span> oj</span><span style=3D"co=
lor:#660">{</span><span style=3D"color:#066">1</span><span style=3D"color:#=
660">};</span><span><br>
</span><span style=3D"color:#008">static_assert</span><span style=3D"color:=
#660">(</span><span>oi </span><span style=3D"color:#660">=3D=3D</span><span=
> oj</span><span style=3D"color:#660">,</span><span> </span><span style=3D"=
color:#080">"!"</span><span style=3D"color:#660">);</span><span><br>
</span></div></code></div><br>And he will receive a compiler error saying t=
hat operator=3D=3D is not a constexpr function: it has been only defined wi=
th constexpr specifier. He will accuse the standard library vendor that the=
library is not compliant with C++ Standard. But the vendor will say "the s=
tandard only requires that we annotate operator=3D=3D with constexpr; but n=
ot that these operators must be constexpr functions".<span><font color=3D"#=
888888"><br>
<br></font></span></div></blockquote><div><br>Then I'm missing somet=
hing (and if I am, something IS missing :)<br> <br>How does including =
the constexpr specifier in the definition of the template function operator=
=3D=3D fails to "make it a constexpr function"?<br>
<br>Or else, how do you make such a thing other than by including the const=
expr specifier in the definition (or declaration but it doesn't matter to t=
his argument)?<br><br>Or are are you saying that we put that in the proposa=
l, then the std text includes something like:<br>
<br>constexpr bool operator =3D=3D ( bla bla )<br><br>BUT then a library im=
plementer drops the constexpr?<br><br>That's not possible. Such an implemen=
tation would be non-conforming.<br></div></div></div></blockquote></div>
<div><br>Let me illustrate this with an example:<br><div style=3D"backgroun=
d-color:rgb(250,250,250);border-color:rgb(187,187,187);border-style:solid;b=
order-width:1px;word-wrap:break-word"><code><div><span style=3D"color:#008"=
>struct</span><span> </span><span style=3D"color:#606">Trash</span><span st=
yle=3D"color:#660">{};</span><span> </sp=
an><span style=3D"color:#800">// just a dummy tag </span><span><br>
</span><span style=3D"color:#008">constexpr</span><span> </span><span style=
=3D"color:#606">Trash</span><span> trash</span><span style=3D"color:#660">{=
};</span><span> </span><span style=3D"color:#800">//</span><span><br>
<br></span><span style=3D"color:#008">constexpr</span><span> </span><span s=
tyle=3D"color:#008">bool</span><span> equal_impl</span><span style=3D"color=
:#660">(</span><span style=3D"color:#606">Trash</span><span> </span><span s=
tyle=3D"color:#008">const</span><span style=3D"color:#660">&,</span><sp=
an> </span><span style=3D"color:#606">Trash</span><span> </span><span style=
=3D"color:#008">const</span><span style=3D"color:#660">&)</span><span> =
<br>
</span><span style=3D"color:#660">{</span><span> <br> </span><span st=
yle=3D"color:#008">return</span><span> </span><span style=3D"color:#008">tr=
ue</span><span style=3D"color:#660">;</span><span> <br></span><span style=
=3D"color:#660">}</span><span><br>
<br></span><span style=3D"color:#008">template</span><span> </span><span st=
yle=3D"color:#660"><</span><span style=3D"color:#008">class</span><span>=
T</span><span style=3D"color:#660">></span><span> =
</span><span style=3D"color:#800">// no constexpr</span><span><br>
</span><span style=3D"color:#008">bool</span><span> equal_impl</span><span =
style=3D"color:#660">(</span><span>T </span><span style=3D"color:#008">cons=
t</span><span style=3D"color:#660">&</span><span> x</span><span style=
=3D"color:#660">,</span><span> T </span><span style=3D"color:#008">const</s=
pan><span style=3D"color:#660">&</span><span> y</span><span style=3D"co=
lor:#660">)</span><span> <br>
</span><span style=3D"color:#660">{</span><span> <br> doSomethingAtRu=
ntime</span><span style=3D"color:#660">();</span><span><br> </span><s=
pan style=3D"color:#008">return</span><span> x </span><span style=3D"color:=
#660">=3D=3D</span><span> y</span><span style=3D"color:#660">;</span><span>=
<br>
</span><span style=3D"color:#660">}</span><span><br><br></span><span style=
=3D"color:#008">template</span><span> </span><span style=3D"color:#660"><=
;</span><span style=3D"color:#008">class</span><span> T</span><span style=
=3D"color:#660">></span><span><br>
</span><span style=3D"color:#008">constexpr</span><span> </span><span style=
=3D"color:#008">bool</span><span> equal</span><span style=3D"color:#660">(<=
/span><span>T </span><span style=3D"color:#008">const</span><span style=3D"=
color:#660">&</span><span> x</span><span style=3D"color:#660">,</span><=
span> T </span><span style=3D"color:#008">const</span><span style=3D"color:=
#660">&</span><span> y</span><span style=3D"color:#660">)</span><span> =
<br>
</span><span style=3D"color:#660">{</span><span> <br> </span><span st=
yle=3D"color:#008">return</span><span> equal_impl</span><span style=3D"colo=
r:#660">(</span><span>x</span><span style=3D"color:#660">,</span><span> y</=
span><span style=3D"color:#660">);</span><span> <br>
</span><span style=3D"color:#660">}</span></div></code></div><br>You can le=
gally define constexpr function <span style=3D"font-family:courier new,mono=
space">equal </span>like the above, even though no instantiation (except fo=
r a single one for type <span style=3D"font-family:courier new,monospace">T=
rash</span>) renders a constexpr function. <br>
<br>This is allowed by (7.1.5 para 6): <br><div style=3D"margin-left:40px">=
If the instantiated template specialization of a constexpr function templat=
e or member function of a class<br>template would fail to satisfy the requi=
rements for a constexpr function or constexpr constructor, that<br>
specialization is not a constexpr function or constexpr constructor. [...] =
If no specialization of the template would<br>yield a constexpr function or=
constexpr constructor, the program is ill-formed; no diagnostic required.<=
span><font color=3D"#888888"><br>
</font></span></div></div><span><font color=3D"#888888">
<p></p>
-- <br>
<br>
<br>
<br>
</font></span></blockquote></div><br><br clear=3D"all"><br>-- <br>Fernando =
Cacciola<br>SciSoft Consulting, Founder<br><a href=3D"http://www.scisoft-co=
nsulting.com" target=3D"_blank">http://www.scisoft-consulting.<wbr>com</a><=
br>
</div>
</blockquote>
<p></p>
-- <br />
<br />
<br />
<br />
------=_Part_1087_24777331.1353689454804--
.
Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Fri, 23 Nov 2012 19:17:18 +0200
Raw View
On 23 November 2012 18:50, Nicol Bolas <jmckesson@gmail.com> wrote:
>> A call to equal(2,2) would not be a const expression because it would fall
>> to the non-constexpr impl.
>> A call to equal(trash,trash) OTOH will be.
>> Now, what's the problem here? What would you like to improve? and most
>> importantly, how does any of this relate to optional<>? :)
> He wants the standard itself to guarantee what will and will not be a true
> constexpr. He wants the standard to provide guarantees about the usage of
> these observers that will force all conforming implementations to all be
> constexpr in the same way.
> All the standard would say about something like `equal` is that it is
> declared `constexpr`. That means nothing about the circumstances under which
> a particular implementation is actually a constant expression. He wants the
> standard to provide more information about when uses of optional will be
> constant expressions and when they will not.
I see now what Fernando is saying, and we don't need to specify the
circumstances.
Rough example:
template <class T>
struct optional
{
bool engaged; // exposition only
union {
char dummy[sizeof(T];
T val;
} data; // exposition only
};
template <class T> bool operator==(const optional<T>& a, const optional<T> b);
Returns: a.engaged && b.engaged && (a.data.val == b.data.val) ||
!a.engaged && !b.engaged
(pardon me for any silly mistakes...)
We don't need to specify any additional circumstances. Given that
returns clause,
if a and b are constexpr, so will operator==. If either isn't, neither
will the operator==.
And given that returns clause, there's not a damned thing a conforming
implementation
can do about it. :)
Right?
--
.
Author: Fernando Cacciola <fernando.cacciola@gmail.com>
Date: Fri, 23 Nov 2012 14:32:01 -0300
Raw View
--14dae9340d5d87720f04cf2cf84e
Content-Type: text/plain; charset=ISO-8859-1
On Fri, Nov 23, 2012 at 2:17 PM, Ville Voutilainen <
ville.voutilainen@gmail.com> wrote:
> On 23 November 2012 18:50, Nicol Bolas <jmckesson@gmail.com> wrote:
> >> A call to equal(2,2) would not be a const expression because it would
> fall
> >> to the non-constexpr impl.
> >> A call to equal(trash,trash) OTOH will be.
> >> Now, what's the problem here? What would you like to improve? and most
> >> importantly, how does any of this relate to optional<>? :)
> > He wants the standard itself to guarantee what will and will not be a
> true
> > constexpr. He wants the standard to provide guarantees about the usage of
> > these observers that will force all conforming implementations to all be
> > constexpr in the same way.
> > All the standard would say about something like `equal` is that it is
> > declared `constexpr`. That means nothing about the circumstances under
> which
> > a particular implementation is actually a constant expression. He wants
> the
> > standard to provide more information about when uses of optional will be
> > constant expressions and when they will not.
>
> I see now what Fernando is saying, and we don't need to specify the
> circumstances.
>
> Rough example:
>
> template <class T>
> struct optional
> {
> bool engaged; // exposition only
> union {
> char dummy[sizeof(T];
> T val;
> } data; // exposition only
> };
>
> template <class T> bool operator==(const optional<T>& a, const optional<T>
> b);
> Returns: a.engaged && b.engaged && (a.data.val == b.data.val) ||
> !a.engaged && !b.engaged
>
> (pardon me for any silly mistakes...)
>
> We don't need to specify any additional circumstances. Given that
> returns clause,
> if a and b are constexpr, so will operator==. If either isn't, neither
> will the operator==.
> And given that returns clause, there's not a damned thing a conforming
> implementation
> can do about it. :)
>
> Right?
>
>
Exactly
..
Well, almost. We still need to specify that as
template <class T> constexpr
bool operator==(const optional<T>& a, const optional<T> b);
otherwise, this == will not be constexpr even if a and b are.
> --
>
>
>
>
--
Fernando Cacciola
SciSoft Consulting, Founder
http://www.scisoft-consulting.com
--
--14dae9340d5d87720f04cf2cf84e
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div class=3D"gmail_extra"><div class=3D"gmail_quote">On Fri, Nov 23, 2012 =
at 2:17 PM, Ville Voutilainen <span dir=3D"ltr"><<a href=3D"mailto:ville=
..voutilainen@gmail.com" target=3D"_blank">ville.voutilainen@gmail.com</a>&g=
t;</span> wrote:<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-=
left:1px solid rgb(204,204,204);padding-left:1ex"><div class=3D"im">On 23 N=
ovember 2012 18:50, Nicol Bolas <<a href=3D"mailto:jmckesson@gmail.com">=
jmckesson@gmail.com</a>> wrote:<br>
>> A call to equal(2,2) would not be a const expression because it wo=
uld fall<br>
>> to the non-constexpr impl.<br>
>> A call to equal(trash,trash) OTOH will be.<br>
>> Now, what's the problem here? What would you like to improve? =
and most<br>
>> importantly, how does any of this relate to optional<>? :)<b=
r>
> He wants the standard itself to guarantee what will and will not be a =
true<br>
> constexpr. He wants the standard to provide guarantees about the usage=
of<br>
> these observers that will force all conforming implementations to all =
be<br>
> constexpr in the same way.<br>
> All the standard would say about something like `equal` is that it is<=
br>
> declared `constexpr`. That means nothing about the circumstances under=
which<br>
> a particular implementation is actually a constant expression. He want=
s the<br>
> standard to provide more information about when uses of optional will =
be<br>
> constant expressions and when they will not.<br>
<br>
</div>I see now what Fernando is saying, and we don't need to specify t=
he<br>
circumstances.<br>
<br>
Rough example:<br>
<br>
template <class T><br>
struct optional<br>
{<br>
=A0 =A0 bool engaged; // exposition only<br>
=A0 =A0 union {<br>
=A0 =A0 =A0 =A0 char dummy[sizeof(T];<br>
=A0 =A0 =A0 =A0 T val;<br>
=A0 =A0 } data; // exposition only<br>
};<br>
<br>
template <class T> bool operator=3D=3D(const optional<T>& a=
, const optional<T> b);<br>
Returns: a.engaged && b.engaged && (a.data.val =3D=3D b.dat=
a.val) ||<br>
!a.engaged && !b.engaged<br>
<br>
(pardon me for any silly mistakes...)<br>
<br>
We don't need to specify any additional circumstances. Given that<br>
returns clause,<br>
if a and b are constexpr, so will operator=3D=3D. If either isn't, neit=
her<br>
will the operator=3D=3D.<br>
And given that returns clause, there's not a damned thing a conforming<=
br>
implementation<br>
can do about it. :)<br>
<br>
Right?<br>
<span class=3D""><font color=3D"#888888"><br></font></span></blockquote><di=
v><br>Exactly<br>.<br>Well, almost. We still need to specify that as<br><br=
>template <class T> constexpr<br>bool operator=3D=3D(const optional&l=
t;T>& a, const optional<T> b);<br>
<br>otherwise, this =3D=3D will not be constexpr even if a and b are.<br><b=
r><br>
<br>=A0<br></div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px =
0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><span cl=
ass=3D""><font color=3D"#888888">
--<br>
<br>
<br>
<br>
</font></span></blockquote></div><br><br clear=3D"all"><br>-- <br>Fernando =
Cacciola<br>SciSoft Consulting, Founder<br><a href=3D"http://www.scisoft-co=
nsulting.com">http://www.scisoft-consulting.com</a><br>
</div>
<p></p>
-- <br />
<br />
<br />
<br />
--14dae9340d5d87720f04cf2cf84e--
.
Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Fri, 23 Nov 2012 19:36:15 +0200
Raw View
On 23 November 2012 19:32, Fernando Cacciola
<fernando.cacciola@gmail.com> wrote:
> Exactly
> Well, almost. We still need to specify that as
> template <class T> constexpr
> bool operator==(const optional<T>& a, const optional<T> b);
> otherwise, this == will not be constexpr even if a and b are.
Oops. Sorry. But I think you understood the point I was desperately
trying to make,
the specification of the effects of the operator== will
deterministically yield constexpr
results if possible, without risk that a conforming implementation
would disagree, modulo
bugs.
--
.
Author: Fernando Cacciola <fernando.cacciola@gmail.com>
Date: Fri, 23 Nov 2012 14:41:56 -0300
Raw View
--e89a8fb1f84a0435a204cf2d1c5f
Content-Type: text/plain; charset=ISO-8859-1
On Fri, Nov 23, 2012 at 2:36 PM, Ville Voutilainen <
ville.voutilainen@gmail.com> wrote:
> On 23 November 2012 19:32, Fernando Cacciola
> <fernando.cacciola@gmail.com> wrote:
> > Exactly
> > Well, almost. We still need to specify that as
> > template <class T> constexpr
> > bool operator==(const optional<T>& a, const optional<T> b);
> > otherwise, this == will not be constexpr even if a and b are.
>
> Oops. Sorry. But I think you understood the point I was desperately
> trying to make,
> the specification of the effects of the operator== will
> deterministically yield constexpr
> results if possible, without risk that a conforming implementation
> would disagree, modulo
> bugs.
>
>
Right.
--
Fernando Cacciola
SciSoft Consulting, Founder
http://www.scisoft-consulting.com
--
--e89a8fb1f84a0435a204cf2d1c5f
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div class=3D"gmail_extra"><div class=3D"gmail_quote">On Fri, Nov 23, 2012 =
at 2:36 PM, Ville Voutilainen <span dir=3D"ltr"><<a href=3D"mailto:ville=
..voutilainen@gmail.com" target=3D"_blank">ville.voutilainen@gmail.com</a>&g=
t;</span> wrote:<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex">On 23 November 2012 19:32, Fernando Cacciola=
<br>
<<a href=3D"mailto:fernando.cacciola@gmail.com">fernando.cacciola@gmail.=
com</a>> wrote:<br>
> Exactly<br>
<div class=3D"im">> Well, almost. We still need to specify that as<br>
> template <class T> constexpr<br>
> bool operator=3D=3D(const optional<T>& a, const optional<=
T> b);<br>
> otherwise, this =3D=3D will not be constexpr even if a and b are.<br>
<br>
</div>Oops. Sorry. But I think you understood the point I was desperately<b=
r>
trying to make,<br>
the specification of the effects of the operator=3D=3D will<br>
deterministically yield constexpr<br>
results if possible, without risk that a conforming implementation<br>
would disagree, modulo<br>
bugs.<br>
<span class=3D"HOEnZb"><font color=3D"#888888"><br></font></span></blockquo=
te><div><br>Right.<br><br></div></div><br><br clear=3D"all"><br>-- <br>Fern=
ando Cacciola<br>SciSoft Consulting, Founder<br><a href=3D"http://www.sciso=
ft-consulting.com">http://www.scisoft-consulting.com</a><br>
</div>
<p></p>
-- <br />
<br />
<br />
<br />
--e89a8fb1f84a0435a204cf2d1c5f--
.
Author: Jeffrey Yasskin <jyasskin@googlers.com>
Date: Fri, 23 Nov 2012 10:09:29 -0800
Raw View
On Fri, Nov 23, 2012 at 5:57 AM, Andrzej Krzemie=C5=84ski <akrzemi1@gmail.c=
om> wrote:
>
>> So, I would probably suggest option 2 since it's the least complicated
>> that still matches what the LWG thought it wanted in Portland, but I'm
>> going to vote for the proposal regardless.
>
>
> We will propose option 2 then. I have one other question to the Standard
> experts. How should we express in the standardese the requirement that
> certain operations must be evaluable at compile-time? The way 'constexpr'=
is
> defined, (7.1.5 para 6) if you declare a function template constexpr you =
are
> not required (neither by the library standardese nor by the language) tha=
t
> the instantiations of your template to be constexpr functions (provided t=
hat
> there exists only one single instantiation that is in fact a constexpr
> function).
>
> To illustrate what I mean, if n3471 is incorporated, the standardese for
> 20.3.3 (tuple comparison) would read:
>
> template <class T1, class T2>
> constexpr bool operator=3D=3D(const pair<T1, T2>& x, const pair<T1, T2>=
& y);
>
> Returns: x.first =3D=3D y.first && x.second =3D=3D y.second.
>
> But it does not require of the operator that p =3D=3D p is a core constan=
t
> expression even if decltype(p) is pair<int, int>. Because constexpr
> function template instantiations are not required to render constexpr
> functions.
>
> We would still have to add a requirement that instantiations of this
> templates shall render constexpr functions for all types for which T1's a=
nd
> T2's operator=3D=3D are constexpr functions. Am I right?
IMO, if all of the other similar types in the current standard have a
problem, you don't need to worry about solving that problem in your
new type. You can file a defect report about the other types, and most
likely your type will get fixed along with all the other ones when the
DR is resolved.
Jeffrey
--=20
.
Author: =?ISO-8859-1?Q?Daniel_Kr=FCgler?= <daniel.kruegler@gmail.com>
Date: Fri, 23 Nov 2012 21:02:07 +0100
Raw View
--047d7bacbff0f46ddb04cf2f0e22
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
2012/11/23 Andrzej Krzemie=C5=84ski <akrzemi1@gmail.com>
>
> So, I would probably suggest option 2 since it's the least complicated
>> that still matches what the LWG thought it wanted in Portland, but I'm
>> going to vote for the proposal regardless.
>>
>
> We will propose option 2 then. I have one other question to the Standard
> experts. How should we express in the standardese the requirement that
> certain operations must be evaluable at compile-time? The way 'constexpr'
> is defined, (7.1.5 para 6) if you declare a function template constexpr y=
ou
> are not required (neither by the library standardese nor by the language)
> that the instantiations of your template to be constexpr functions
> (provided that there exists only one single instantiation that is in fact=
a
> constexpr function).
>
> To illustrate what I mean, if n3471 is incorporated, the standardese for
> 20.3.3 (tuple comparison) would read:
>
> template <class T1, class T2>
> constexpr bool operator=3D=3D(const pair<T1, T2>& x, const pair<T1, T2>=
& y);
>
> *Returns: *x.first =3D=3D y.first && x.second =3D=3D y.second.
>
> But it does not require of the operator that p =3D=3D p is a core constan=
t
> expression even if decltype(p) is pair<int, int>. Because constexpr
> function template instantiations are not required to render constexpr
> functions.
>
> We would still have to add a requirement that instantiations of this
> templates shall render constexpr functions for all types for which T1's
> and T2's operator=3D=3D are constexpr functions. Am I right?
>
This is essentially correct. I have not read all contributions to this
thread, therefore I'm risking that I repeat something already said: During
the acceptance of several "constexpr" proposals we have already ensured
comparable wording, e.g.
"The defaulted move and copy constructor, respectively, of pair shall be a
constexpr function if and only if
all required element-wise initializations for copy and move, respectively,
would satisfy the requirements for
a constexpr function."
These are necessarily "conditional" requirements, but if you want
unconditional one, it is easy to rephrase it accordingly.
For istream_iterator we have similar requirements for the default
constructor:
"If T is a literal type, then this constructor shall be a constexpr
constructor."
and istreambuf_iterator has already unconstrained constexpr (and
triviality) requirements:
"All specializations of istreambuf_iterator shall have a trivial copy
constructor, a constexpr default constructor, and a trivial destructor."
Similar for atomic type requirements.
- Daniel
--=20
--047d7bacbff0f46ddb04cf2f0e22
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div class=3D"gmail_quote">2012/11/23 Andrzej Krzemie=C5=84ski <span dir=3D=
"ltr"><<a href=3D"mailto:akrzemi1@gmail.com" target=3D"_blank">akrzemi1@=
gmail.com</a>></span><br><blockquote class=3D"gmail_quote" style=3D"marg=
in:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div class=3D"im"><br><blockquote class=3D"gmail_quote" style=3D"margin:0;m=
argin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex">So, I would p=
robably suggest option 2 since it's the least complicated
<br>that still matches what the LWG thought it wanted in Portland, but I=
9;m
<br>going to vote for the proposal regardless.
<br></blockquote></div><div><br>We will propose option 2 then. I have one o=
ther question to the Standard experts. How should we express in the standar=
dese the requirement that certain operations must be evaluable at compile-t=
ime? The way 'constexpr' is defined, (7.1.5 para 6) if you declare =
a function template constexpr you are not required (neither by the library =
standardese nor by the language) that the instantiations of your template t=
o be constexpr functions (provided that there exists only one single instan=
tiation that is in fact a constexpr function). <br>
<br>To illustrate what I mean, if n3471 is incorporated, the standardese fo=
r 20.3.3 (tuple comparison) would read:<br><br><div style=3D"margin-left:40=
px"><span style=3D"font-family:courier new,monospace">template <class T1=
, class T2></span><br>
<span style=3D"font-family:courier new,monospace">=C2=A0 constexpr bool ope=
rator=3D=3D(const pair<T1, T2>& x, const pair<T1, T2>& =
y);</span><br><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 <i>Returns:=C2=A0 </i><span s=
tyle=3D"font-family:courier new,monospace">x.first =3D=3D y.first &&=
; x.second =3D=3D y.second</span>.<br>
</div> <br>But it does not require of the operator that <span style=3D"font=
-family:courier new,monospace">p =3D=3D p</span> is a core constant express=
ion even if <span style=3D"font-family:courier new,monospace">decltype(p)</=
span> is <span style=3D"font-family:courier new,monospace">pair<int, int=
></span>.=C2=A0 Because constexpr function template instantiations are n=
ot required to render constexpr functions.<br>
<br>We would still have to add a requirement that instantiations of this te=
mplates shall render constexpr functions for all types for which <span styl=
e=3D"font-family:courier new,monospace">T1</span>'s and <span style=3D"=
font-family:courier new,monospace">T2</span>'s operator=3D=3D are const=
expr functions. Am I right?<span class=3D"HOEnZb"><font color=3D"#888888"><=
br>
</font></span></div></blockquote><div><br></div></div>This is essentially c=
orrect. I have not read all contributions to this thread, therefore I'm=
risking that I repeat something already said: During the acceptance of sev=
eral "constexpr" proposals we have already ensured comparable wor=
ding, e.g.<br>
<br>"The defaulted move and copy constructor, respectively, of pair sh=
all be a constexpr function if and only if<br>all required element-wise ini=
tializations for copy and move, respectively, would satisfy the requirement=
s for<br>
a constexpr function."<br><br>These are necessarily "conditional&=
quot; requirements, but if you want unconditional one, it is easy to rephra=
se it accordingly.<br><br>For istream_iterator we have similar requirements=
for the default constructor:<br>
<br>"If T is a literal type, then this constructor shall be a constexp=
r constructor."<br><br>and istreambuf_iterator has already unconstrain=
ed constexpr (and triviality) requirements:<br><br>"All specialization=
s of istreambuf_iterator shall have a trivial copy constructor, a constexpr=
default constructor, and a trivial destructor."<br>
<br>Similar for atomic type requirements.<br><br>- Daniel<br><br>
<p></p>
-- <br />
<br />
<br />
<br />
--047d7bacbff0f46ddb04cf2f0e22--
.
Author: Richard Smith <richard@metafoo.co.uk>
Date: Fri, 23 Nov 2012 21:04:40 -0800
Raw View
On Fri, Nov 23, 2012 at 7:34 AM, Ville Voutilainen
<ville.voutilainen@gmail.com> wrote:
> On 23 November 2012 17:28, Fernando Cacciola
> <fernando.cacciola@gmail.com> wrote:
>> Then I'm missing something (and if I am, something IS missing :)
>> How does including the constexpr specifier in the definition of the template
>> function operator== fails to "make it a constexpr function"?
>
> Not all instantiations of a function template marked constexpr need to
> be constexpr.
Note that CWG intends to change this rule (see core issue 1358) such
that every instantiation of a constexpr function template is
constexpr. You should not be worrying about whether the function is
constexpr anyway, since requiring a function to be constexpr does not
require it to actually produce a constant expression for any
particular inputs. The relevant issue is whether certain operations
produce core constant expressions, and that is what the library
wording should describe. The current library requirements for
constexpr are frequently underspecified because of this.
--
.
Author: =?UTF-8?Q?Andrzej_Krzemie=C5=84ski?= <akrzemi1@gmail.com>
Date: Fri, 23 Nov 2012 23:43:20 -0800 (PST)
Raw View
------=_Part_188_30907125.1353743000306
Content-Type: text/plain; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable
W dniu pi=B1tek, 23 listopada 2012 17:50:55 UTC+1 u=BFytkownik Nicol Bolas=
=20
napisa=B3:
>
>
>
> On Friday, November 23, 2012 8:00:42 AM UTC-8, Fernando Cacciola wrote:
>>
>> You lost me :)
>>
>> I agree that you example is valid.
>>
>> A call to equal(2,2) would not be a const expression because it would=20
>> fall to the non-constexpr impl.
>> A call to equal(trash,trash) OTOH will be.
>>
>> Now, what's the problem here? What would you like to improve? and most=
=20
>> importantly, how does any of this relate to optional<>? :)
>>
>
> He wants the standard itself to *guarantee* what will and will not be a=
=20
> true constexpr. He wants the standard to provide guarantees about the usa=
ge=20
> of these observers that will *force* all conforming implementations to=20
> all be constexpr in the same way.
>
> All the standard would say about something like `equal` is that it is=20
> declared `constexpr`. That means nothing about the circumstances under=20
> which a particular implementation is actually a constant expression. He=
=20
> wants the standard to provide more information about when uses of optiona=
l=20
> will be constant expressions and when they will not.
>
Nicol summarized it quite well. I wanted to show whith the example that=20
guaranteeing that our template is declared with "constexpr" specifier, does=
=20
not guarantee that its instantiations are constexpr functions. And we would=
=20
like to offer even the second guarantee. =20
--=20
------=_Part_188_30907125.1353743000306
Content-Type: text/html; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable
<br><br>W dniu pi=B1tek, 23 listopada 2012 17:50:55 UTC+1 u=BFytkownik Nico=
l Bolas napisa=B3:<blockquote class=3D"gmail_quote" style=3D"margin: 0;marg=
in-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><br><br>On F=
riday, November 23, 2012 8:00:42 AM UTC-8, Fernando Cacciola wrote:<blockqu=
ote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1=
px #ccc solid;padding-left:1ex">You lost me :)<br><br>I agree that you exam=
ple is valid.<br><br>A call to equal(2,2) would not be a const expression b=
ecause it would fall to the non-constexpr impl.<br>A call to equal(trash,tr=
ash) OTOH will be.<br><br>Now, what's the problem here? What would you like=
to improve? and most importantly, how does any of this relate to optional&=
lt;>? :)<br></blockquote><div><br>He wants the standard itself to <i>gua=
rantee</i> what will and will not be a true constexpr. He wants the standar=
d to provide guarantees about the usage of these observers that will <i>for=
ce</i> all conforming implementations to all be constexpr in the same way.<=
br><br>All the standard would say about something like `equal` is that it i=
s declared `constexpr`. That means nothing about the circumstances under wh=
ich a particular implementation is actually a constant expression. He wants=
the standard to provide more information about when uses of optional will =
be constant expressions and when they will not.</div></blockquote><div><br>=
Nicol summarized it quite well. I wanted to show whith the example that gua=
ranteeing that our template is declared with "constexpr" specifier, does no=
t guarantee that its instantiations are constexpr functions. And we would l=
ike to offer even the second guarantee. <br></div><br>
<p></p>
-- <br />
<br />
<br />
<br />
------=_Part_188_30907125.1353743000306--
.
Author: =?UTF-8?Q?Andrzej_Krzemie=C5=84ski?= <akrzemi1@gmail.com>
Date: Fri, 23 Nov 2012 23:53:56 -0800 (PST)
Raw View
------=_Part_16_14652822.1353743636090
Content-Type: text/plain; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable
W dniu pi=B1tek, 23 listopada 2012 18:32:44 UTC+1 u=BFytkownik Fernando=20
Cacciola napisa=B3:
>
> On Fri, Nov 23, 2012 at 2:17 PM, Ville Voutilainen <ville.vo...@gmail.com=
<javascript:>
> > wrote:
>
>>
>> I see now what Fernando is saying, and we don't need to specify the
>> circumstances.
>>
>> Rough example:
>>
>> template <class T>
>> struct optional
>> {
>> bool engaged; // exposition only
>> union {
>> char dummy[sizeof(T];
>> T val;
>> } data; // exposition only
>> };
>>
>> template <class T> bool operator=3D=3D(const optional<T>& a, const=20
>> optional<T> b);
>> Returns: a.engaged && b.engaged && (a.data.val =3D=3D b.data.val) ||
>> !a.engaged && !b.engaged
>>
>> (pardon me for any silly mistakes...)
>>
>> We don't need to specify any additional circumstances. Given that
>> returns clause,
>> if a and b are constexpr, so will operator=3D=3D. If either isn't, neith=
er
>> will the operator=3D=3D.
>> And given that returns clause, there's not a damned thing a conforming
>> implementation
>> can do about it. :)
>>
>> Right?
>>
>>
> Exactly
>
I see your point. I am just not sure if it offers this 100% guarantee=20
against "malicious" but conforming implementations. Whan we specify the=20
"Returns" clause, and ommit the "Effects" clause, does this require that=20
the function in question must do nothing else but return the required=20
expression? Coulr it not do something else before (e.g. some safety checks)=
=20
and then return? Perhaps the fact that it is an observer function imposes=
=20
some additional constraints?=20
But if this is a bug in the standard rather than in the library, then=20
perhaps I am too much cautious. However, the situation is less clear for me=
=20
when it comes to constructors: they do mutate data, and perhaps we should=
=20
make the constraints more explicit. Especially that adding the additional=
=20
wording is not difficult.=20
--=20
------=_Part_16_14652822.1353743636090
Content-Type: text/html; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable
<br><br>W dniu pi=B1tek, 23 listopada 2012 18:32:44 UTC+1 u=BFytkownik Fern=
ando Cacciola napisa=B3:<blockquote class=3D"gmail_quote" style=3D"margin: =
0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div><=
div class=3D"gmail_quote">On Fri, Nov 23, 2012 at 2:17 PM, Ville Voutilaine=
n <span dir=3D"ltr"><<a href=3D"javascript:" target=3D"_blank" gdf-obfus=
cated-mailto=3D"TiI-bpCU_kAJ">ville.vo...@gmail.com</a>></span> wrote:<b=
r>
<blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-=
left:1px solid rgb(204,204,204);padding-left:1ex"><div><br>
</div>I see now what Fernando is saying, and we don't need to specify the<b=
r>
circumstances.<br>
<br>
Rough example:<br>
<br>
template <class T><br>
struct optional<br>
{<br>
bool engaged; // exposition only<br>
union {<br>
char dummy[sizeof(T];<br>
T val;<br>
} data; // exposition only<br>
};<br>
<br>
template <class T> bool operator=3D=3D(const optional<T>& a=
, const optional<T> b);<br>
Returns: a.engaged && b.engaged && (a.data.val =3D=3D b.dat=
a.val) ||<br>
!a.engaged && !b.engaged<br>
<br>
(pardon me for any silly mistakes...)<br>
<br>
We don't need to specify any additional circumstances. Given that<br>
returns clause,<br>
if a and b are constexpr, so will operator=3D=3D. If either isn't, neither<=
br>
will the operator=3D=3D.<br>
And given that returns clause, there's not a damned thing a conforming<br>
implementation<br>
can do about it. :)<br>
<br>
Right?<br>
<span><font color=3D"#888888"><br></font></span></blockquote><div><br>Exact=
ly<br></div></div></div></blockquote><div><br>I see your point. I am just n=
ot sure if it offers this 100% guarantee against "malicious" but conforming=
implementations. Whan we specify the "Returns" clause, and ommit the "Effe=
cts" clause, does this require that the function in question must do nothin=
g else but return the required expression? Coulr it not do something else b=
efore (e.g. some safety checks) and then return? Perhaps the fact that it i=
s an observer function imposes some additional constraints? <br><br>But if =
this is a bug in the standard rather than in the library, then perhaps I am=
too much cautious. However, the situation is less clear for me when it com=
es to constructors: they do mutate data, and perhaps we should make the con=
straints more explicit. Especially that adding the additional wording is no=
t difficult. <br></div>
<p></p>
-- <br />
<br />
<br />
<br />
------=_Part_16_14652822.1353743636090--
.
Author: =?UTF-8?Q?Andrzej_Krzemie=C5=84ski?= <akrzemi1@gmail.com>
Date: Sat, 24 Nov 2012 00:22:24 -0800 (PST)
Raw View
------=_Part_205_6670946.1353745344738
Content-Type: text/plain; charset=ISO-8859-1
> I see your point. I am just not sure if it offers this 100% guarantee
> against "malicious" but conforming implementations. Whan we specify the
> "Returns" clause, and ommit the "Effects" clause, does this require that
> the function in question must do nothing else but return the required
> expression? Coulr it not do something else before (e.g. some safety checks)
> and then return? Perhaps the fact that it is an observer function imposes
> some additional constraints?
>
> But if this is a bug in the standard rather than in the library, then
> perhaps I am too much cautious. However, the situation is less clear for me
> when it comes to constructors: they do mutate data, and perhaps we should
> make the constraints more explicit. Especially that adding the additional
> wording is not difficult.
>
Or, to express my concern in other words, do you thing the following
implementation
struct Trash{}; // just a dummy tag
constexpr bool equal_impl(Trash const&, Trash const&)
{
return true;
}
template <class T> // no constexpr
bool equal_impl(T const& x, T const& y)
{
doSomethingAtRuntime();
return x == y;
}
template <class T>
constexpr bool equal(T const& x, T const& y)
{
return equal_impl(x, y);
}
Satisfies the following formal requirements:
template <class T>
constexpr bool equal(const T& x, const T& y);
*Returns: *x == y.
--
------=_Part_205_6670946.1353745344738
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<br><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex=
;border-left: 1px #ccc solid;padding-left: 1ex;"><div>I see your point. I a=
m just not sure if it offers this 100% guarantee against "malicious" but co=
nforming implementations. Whan we specify the "Returns" clause, and ommit t=
he "Effects" clause, does this require that the function in question must d=
o nothing else but return the required expression? Coulr it not do somethin=
g else before (e.g. some safety checks) and then return? Perhaps the fact t=
hat it is an observer function imposes some additional constraints? <br><br=
>But if this is a bug in the standard rather than in the library, then perh=
aps I am too much cautious. However, the situation is less clear for me whe=
n it comes to constructors: they do mutate data, and perhaps we should make=
the constraints more explicit. Especially that adding the additional wordi=
ng is not difficult. <br></div></blockquote><div><br>Or, to express my conc=
ern in other words, do you thing the following implementation<br><br><div s=
tyle=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,187);bor=
der-style:solid;border-width:1px;word-wrap:break-word"><code><div><span sty=
le=3D"color:#008">struct</span><span style=3D"color:#000"> </span><span sty=
le=3D"color:#606">Trash</span><span style=3D"color:#660">{};</span><span st=
yle=3D"color:#000"> </span><span style=
=3D"color:#800">// just a dummy tag </span><span style=3D"color:#000"></spa=
n><span style=3D"color:#000"><br><br></span><span style=3D"color:#008">cons=
texpr</span><span style=3D"color:#000"> </span><span style=3D"color:#008">b=
ool</span><span style=3D"color:#000"> equal_impl</span><span style=3D"color=
:#660">(</span><span style=3D"color:#606">Trash</span><span style=3D"color:=
#000"> </span><span style=3D"color:#008">const</span><span style=3D"color:#=
660">&,</span><span style=3D"color:#000"> </span><span style=3D"color:#=
606">Trash</span><span style=3D"color:#000"> </span><span style=3D"color:#0=
08">const</span><span style=3D"color:#660">&)</span><span style=3D"colo=
r:#000"> <br></span><span style=3D"color:#660">{</span><span style=3D"color=
:#000"> <br> </span><span style=3D"color:#008">return</span><span sty=
le=3D"color:#000"> </span><span style=3D"color:#008">true</span><span style=
=3D"color:#660">;</span><span style=3D"color:#000"> <br></span><span style=
=3D"color:#660">}</span><span style=3D"color:#000"><br><br></span><span sty=
le=3D"color:#008">template</span><span style=3D"color:#000"> </span><span s=
tyle=3D"color:#660"><</span><span style=3D"color:#008">class</span><span=
style=3D"color:#000"> T</span><span style=3D"color:#660">></span><span =
style=3D"color:#000"> </span><span style=3D"colo=
r:#800">// no constexpr</span><span style=3D"color:#000"><br></span><span s=
tyle=3D"color:#008">bool</span><span style=3D"color:#000"> equal_impl</span=
><span style=3D"color:#660">(</span><span style=3D"color:#000">T </span><sp=
an style=3D"color:#008">const</span><span style=3D"color:#660">&</span>=
<span style=3D"color:#000"> x</span><span style=3D"color:#660">,</span><spa=
n style=3D"color:#000"> T </span><span style=3D"color:#008">const</span><sp=
an style=3D"color:#660">&</span><span style=3D"color:#000"> y</span><sp=
an style=3D"color:#660">)</span><span style=3D"color:#000"> <br></span><spa=
n style=3D"color:#660">{</span><span style=3D"color:#000"> <br> doSom=
ethingAtRuntime</span><span style=3D"color:#660">();</span><span style=3D"c=
olor:#000"><br> </span><span style=3D"color:#008">return</span><span =
style=3D"color:#000"> x </span><span style=3D"color:#660">=3D=3D</span><spa=
n style=3D"color:#000"> y</span><span style=3D"color:#660">;</span><span st=
yle=3D"color:#000"><br></span><span style=3D"color:#660">}</span><span styl=
e=3D"color:#000"><br><br></span><span style=3D"color:#008">template</span><=
span style=3D"color:#000"> </span><span style=3D"color:#660"><</span><sp=
an style=3D"color:#008">class</span><span style=3D"color:#000"> T</span><sp=
an style=3D"color:#660">></span><span style=3D"color:#000"><br></span><s=
pan style=3D"color:#008">constexpr</span><span style=3D"color:#000"> </span=
><span style=3D"color:#008">bool</span><span style=3D"color:#000"> equal</s=
pan><span style=3D"color:#660">(</span><span style=3D"color:#000">T </span>=
<span style=3D"color:#008">const</span><span style=3D"color:#660">&</sp=
an><span style=3D"color:#000"> x</span><span style=3D"color:#660">,</span><=
span style=3D"color:#000"> T </span><span style=3D"color:#008">const</span>=
<span style=3D"color:#660">&</span><span style=3D"color:#000"> y</span>=
<span style=3D"color:#660">)</span><span style=3D"color:#000"> <br></span><=
span style=3D"color:#660">{</span><span style=3D"color:#000"> <br> </=
span><span style=3D"color:#008">return</span><span style=3D"color:#000"> eq=
ual_impl</span><span style=3D"color:#660">(</span><span style=3D"color:#000=
">x</span><span style=3D"color:#660">,</span><span style=3D"color:#000"> y<=
/span><span style=3D"color:#660">);</span><span style=3D"color:#000"> <br><=
/span><span style=3D"color:#660">}</span></div></code></div> <br>Satis=
fies the following formal requirements:<br><br><br><span style=3D"font-fami=
ly:courier new,monospace">template <class T></span><br><span style=3D=
"font-family:courier new,monospace"> constexpr bool equal(const T&=
; x, const T& y);</span><br><br> <i>Returns:=
</i><span style=3D"font-family:courier new,monospace">x =3D=3D y</sp=
an>.<br></div>
<p></p>
-- <br />
<br />
<br />
<br />
------=_Part_205_6670946.1353745344738--
.
Author: =?UTF-8?Q?Andrzej_Krzemie=C5=84ski?= <akrzemi1@gmail.com>
Date: Mon, 26 Nov 2012 03:19:44 -0800 (PST)
Raw View
------=_Part_345_22709440.1353928784269
Content-Type: text/plain; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable
W dniu pi=B1tek, 23 listopada 2012 16:23:15 UTC+1 u=BFytkownik Fernando=20
Cacciola napisa=B3:
>
>
> On Fri, Nov 23, 2012 at 1:03 PM, Ville Voutilainen <ville.vo...@gmail.com=
<javascript:>
> > wrote:
>
>> On 23 November 2012 16:59, Fernando Cacciola
>> <fernando...@gmail.com <javascript:>> wrote:
>> > IIUC, "const" observers such as operator*, operator =3D=3D, etc... sh=
ould=20
>> be
>> > defined with the constexpr modifier.
>> > The effect is that, with optional<T> being a literal type, in the=20
>> context
>> > where a const optional of a literal type is used in a expression that=
=20
>> calls
>> > such constexpr functions, the result of the call (such as the value of=
=20
>> the
>> > optional or the result of a comparison) is a constant expression.
>> > That is:
>> > constexpr optional<int> o(123);
>> > int a[ *o ] ; // This should be OK.
>> > I also understand that the only requirement in terms of the std text i=
s=20
>> to
>> > include the constexpr specifier where appropriate. I don't think any=
=20
>> extra
>> > clarification is needed.
>>
>> Ah, and if it throws an error for a disengaged optional, it's not
>> constexpr, and that
>> code would be ill-formed.=20
>
>
> Right.
> But it's important to empathize the "if" in your sentence.
>
> constexpr bool foo ( int n )=20
> {
> return n =3D=3D 0 ? throw : n > 0 ;
> }
>
> That definition is OK (I think there is a similar example in the std).
> It is because there are values of the argument n for which the compiler=
=20
> *can* apply the function call substitution, so the function definition=20
> itself is not ill-formed
>
> But then,
>
> int a[ foo(2) ] ;
>
> it's also OK because 2 is constant expression, and the definition of foo=
=20
> allows the compiler to apply a function call substitution that results in=
(=20
> 2 =3D=3D 0 ? <don't-matter> : 2 > 0 ) so the const expression correspondi=
ng to=20
> the result of the call directly evaluates to 'true' with the other branch=
=20
> being simply ignored. [as always IIUC]
>
> OTOH,
>
> void bar(int n )
> {
> int a[ foo(n) ] ;
> }
>
> is ill-formed because the argument to the function is not a constant=20
> expression, the function call substitution results in an expression that=
=20
> cannot be evaluated at compile time, and then it's not possible to ignore=
=20
> the conditional branch with the throw.
>
> But, the program becomes ill-formed at the point the function is in such =
a=20
> way. The function definition is OK and allows for the first example.
>
I just want to add one comment here. Your analysis and Ville's comment=20
might have risen an expectation that std::optional would be checking for=20
being disengaged at compile-time when its contained value is read. While=20
this is possible (I tried to explain the technique here<http://akrzemi1.wor=
dpress.com/2011/05/06/compile-time-computations/>),=20
this will not be the case for std::optional. At least it is not proposed=20
right now. Such error handling mechanism in constexpr functions which works=
=20
both at compile-time and run-time would require a run-time check for being=
=20
engaged:
// NOT PROPOSED!
// precondition: this->is_engaged()
constexpr T const& optional<T>::operator*()
{
return is_engaged() ? // unnecessary run-time cost
contained_value() :
throw logic_error("");
}
This would be an unacceptable cost in a C++ component, given that we=20
already require as precondition that the optional object is engaged. As a=
=20
consequence, you will be able to get the contained value of optional at=20
compile-time, but at your own risk: you have to check yourself if it is=20
engaged:
constexpr oprional<int> oi =3D nullopt;
int array[ *oi ]; // compiles, but will cause UB
--=20
------=_Part_345_22709440.1353928784269
Content-Type: text/html; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable
<br><br>W dniu pi=B1tek, 23 listopada 2012 16:23:15 UTC+1 u=BFytkownik Fern=
ando Cacciola napisa=B3:<blockquote class=3D"gmail_quote" style=3D"margin: =
0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div><=
br><div class=3D"gmail_quote">On Fri, Nov 23, 2012 at 1:03 PM, Ville Voutil=
ainen <span dir=3D"ltr"><<a href=3D"javascript:" target=3D"_blank" gdf-o=
bfuscated-mailto=3D"5snt7-Q375wJ">ville.vo...@gmail.com</a>></span> wrot=
e:<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-=
left:1px solid rgb(204,204,204);padding-left:1ex">On 23 November 2012 16:59=
, Fernando Cacciola<br>
<div><<a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D=
"5snt7-Q375wJ">fernando...@gmail.com</a>> wrote:<br>
> IIUC, "const" observers such as operator*, operator =3D=3D, etc.=
... should be<br>
> defined with the constexpr modifier.<br>
> The effect is that, with optional<T> being a literal type, in th=
e context<br>
> where a const optional of a literal type is used in a expression that =
calls<br>
> such constexpr functions, the result of the call (such as the value of=
the<br>
> optional or the result of a comparison) is a constant expression.<br>
> That is:<br>
> constexpr optional<int> o(123);<br>
> int a[ *o ] ; // This should be OK.<br>
> I also understand that the only requirement in terms of the std text i=
s to<br>
> include the constexpr specifier where appropriate. I don't think any e=
xtra<br>
> clarification is needed.<br>
<br>
</div>Ah, and if it throws an error for a disengaged optional, it's not<br>
constexpr, and that<br>
code would be ill-formed. </blockquote><div><br>Right.<br>But it's importan=
t to empathize the "if" in your sentence.<br><br>constexpr bool foo ( int n=
) <br>{<br> return n =3D=3D 0 ? throw : n > 0 ;<br>}<br>
<br>That definition is OK (I think there is a similar example in the std).<=
br>It is because there are values of the argument n for which the compiler =
*can* apply the function call substitution, so the function definition itse=
lf is not ill-formed<br>
<br>But then,<br><br>int a[ foo(2) ] ;<br><br>it's also OK because 2 is con=
stant expression, and the definition of foo allows the compiler to apply a =
function call substitution that results in ( 2 =3D=3D 0 ? <don't-matter&=
gt; : 2 > 0 ) so the const expression corresponding to the result of the=
call directly evaluates to 'true' with the other branch being simply ignor=
ed. [as always IIUC]<br>
<br>OTOH,<br><br>void bar(int n )<br>{<br> int a[ foo(n) ] ;<br>}<br>=
<br>is ill-formed because the argument to the function is not a constant ex=
pression, the function call substitution results in an expression that cann=
ot be evaluated at compile time, and then it's not possible to ignore the c=
onditional branch with the throw.<br>
<br>But, the program becomes ill-formed at the point the function is in suc=
h a way. The function definition is OK and allows for the first example.<br=
></div></div></div></blockquote><div><br>I just want to add one comment her=
e. Your analysis and Ville's comment might have risen an expectation that s=
td::optional would be checking for being disengaged at compile-time when it=
s contained value is read. While this is possible (I tried to explain the t=
echnique <a href=3D"http://akrzemi1.wordpress.com/2011/05/06/compile-time-c=
omputations/">here</a>), this will not be the case for std::optional. At le=
ast it is not proposed right now. Such error handling mechanism in constexp=
r functions which works both at compile-time and run-time would require a r=
un-time check for being engaged:<br><br><div class=3D"prettyprint" style=3D=
"background-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187); bo=
rder-style: solid; border-width: 1px; word-wrap: break-word;"><code class=
=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"color: #800;"=
class=3D"styled-by-prettify">// NOT PROPOSED!</span><span style=3D"color: =
#000;" class=3D"styled-by-prettify"><br><br></span><span style=3D"color: #8=
00;" class=3D"styled-by-prettify">// precondition: this->is_engaged()</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><s=
pan style=3D"color: #008;" class=3D"styled-by-prettify">constexpr</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> T </span><span styl=
e=3D"color: #008;" class=3D"styled-by-prettify">const</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">&</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> optional</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">>::</span><span style=3D"color: #008;" class=3D"=
styled-by-prettify">operator</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">*()</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"><br></span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">{</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=
</span><span style=3D"color: #008;" class=3D"styled-by-prettify">ret=
urn</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> is_eng=
aged</span><span style=3D"color: #660;" class=3D"styled-by-prettify">()</sp=
an><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"co=
lor: #800;" class=3D"styled-by-prettify">// unnecessary run-time cost</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>  =
; contained_value</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">()</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"><br> <=
/span><span style=3D"color: #008;" class=3D"styled-by-prettify">throw</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"> logic_error</sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span =
style=3D"color: #080;" 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></span><span style=3D"color: #660;"=
class=3D"styled-by-prettify">}</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"><br></span></div></code></div><br>This would be an una=
cceptable cost in a C++ component, given that we already require as precond=
ition that the optional object is engaged. As a consequence, you will be ab=
le to get the contained value of optional at compile-time, but at your own =
risk: you have to check yourself if it is engaged:<br><br><div class=3D"pre=
ttyprint" style=3D"background-color: rgb(250, 250, 250); border-color: rgb(=
187, 187, 187); border-style: solid; border-width: 1px; word-wrap: break-wo=
rd;"><code class=3D"prettyprint"><div class=3D"subprettyprint"><span style=
=3D"color: #008;" class=3D"styled-by-prettify">constexpr</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> oprional</span><span style=
=3D"color: #080;" class=3D"styled-by-prettify"><int></span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"> oi </span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> nullopt</span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br></span><span style=3D"color: #008;" class=3D"st=
yled-by-prettify">int</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"> array</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">[</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> <=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">*</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify">oi </span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">];</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #800;=
" class=3D"styled-by-prettify">// compiles</span><span style=3D"color: #800=
;" class=3D"styled-by-prettify">, but will cause UB</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"><br></span></div></code></div><br>=
<br><br></div>
<p></p>
-- <br />
<br />
<br />
<br />
------=_Part_345_22709440.1353928784269--
.
Author: Fernando Cacciola <fernando.cacciola@gmail.com>
Date: Tue, 27 Nov 2012 15:02:16 -0300
Raw View
--047d7b621df80c7df404cf7ddc49
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Sat, Nov 24, 2012 at 5:22 AM, Andrzej Krzemie=C5=84ski <akrzemi1@gmail.c=
om>wrote:
>
> I see your point. I am just not sure if it offers this 100% guarantee
>> against "malicious" but conforming implementations. Whan we specify the
>> "Returns" clause, and ommit the "Effects" clause, does this require that
>> the function in question must do nothing else but return the required
>> expression? Coulr it not do something else before (e.g. some safety chec=
ks)
>> and then return? Perhaps the fact that it is an observer function impose=
s
>> some additional constraints?
>>
>> But if this is a bug in the standard rather than in the library, then
>> perhaps I am too much cautious. However, the situation is less clear for=
me
>> when it comes to constructors: they do mutate data, and perhaps we shoul=
d
>> make the constraints more explicit. Especially that adding the additiona=
l
>> wording is not difficult.
>>
>
> Or, to express my concern in other words, do you thing the following
> implementation
>
> struct Trash{}; // just a dummy tag
>
> constexpr bool equal_impl(Trash const&, Trash const&)
> {
> return true;
> }
>
> template <class T> // no constexpr
> bool equal_impl(T const& x, T const& y)
> {
> doSomethingAtRuntime();
> return x =3D=3D y;
> }
>
> template <class T>
>
> constexpr bool equal(T const& x, T const& y)
> {
> return equal_impl(x, y);
> }
>
> Satisfies the following formal requirements:
>
>
> template <class T>
> constexpr bool equal(const T& x, const T& y);
>
> *Returns: *x =3D=3D y.
>
> --
>
>
>
>
From my reading of the specification for the constexpr, I would argue that
such an implementation is not conforming because it fails to produce a
constant expression even if the arguments are constant expressions.
I understand your concern and my suggestion was based on the principle of
following what the rest of the std is doing in some places I've looked.
OTOH, this class is a bit distinct because the engaged state participates
in the production of the resulting constant expression, but that is not a
constant expression itself.
Based on the responses from Daniel Krugler and Richard Smith, I think that
some wording to better formalize the expected behavior might be in place.
I'll look around in the std to see what's the best we can say.
--=20
Fernando Cacciola
SciSoft Consulting, Founder
http://www.scisoft-consulting.com
--=20
--047d7b621df80c7df404cf7ddc49
Content-Type: text/html; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable
<div class=3D"gmail_extra"><div class=3D"gmail_quote">On Sat, Nov 24, 2012 =
at 5:22 AM, Andrzej Krzemie=F1ski <span dir=3D"ltr"><<a href=3D"mailto:a=
krzemi1@gmail.com" target=3D"_blank">akrzemi1@gmail.com</a>></span> wrot=
e:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-l=
eft:1px #ccc solid;padding-left:1ex">
<div class=3D"im"><br><blockquote class=3D"gmail_quote" style=3D"margin:0;m=
argin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div>I see yo=
ur point. I am just not sure if it offers this 100% guarantee against "=
;malicious" but conforming implementations. Whan we specify the "=
Returns" clause, and ommit the "Effects" clause, does this r=
equire that the function in question must do nothing else but return the re=
quired expression? Coulr it not do something else before (e.g. some safety =
checks) and then return? Perhaps the fact that it is an observer function i=
mposes some additional constraints? <br>
<br>But if this is a bug in the standard rather than in the library, then p=
erhaps I am too much cautious. However, the situation is less clear for me =
when it comes to constructors: they do mutate data, and perhaps we should m=
ake the constraints more explicit. Especially that adding the additional wo=
rding is not difficult. <br>
</div></blockquote></div><div><br>Or, to express my concern in other words,=
do you thing the following implementation<br><br><div style=3D"background-=
color:rgb(250,250,250);border-color:rgb(187,187,187);border-style:solid;bor=
der-width:1px;word-wrap:break-word">
<code><div><div class=3D"im"><span style=3D"color:#008">struct</span><span =
style> </span><span style=3D"color:#606">Trash</span><span style=3D"color:#=
660">{};</span><span style> =A0 =A0 =A0 =A0 =A0 </span><span style=3D"color=
:#800">// just a dummy tag </span><span style></span><span style><br>
<br></span></div><div class=3D"im"><span style=3D"color:#008">constexpr</sp=
an><span style> </span><span style=3D"color:#008">bool</span><span style> e=
qual_impl</span><span style=3D"color:#660">(</span><span style=3D"color:#60=
6">Trash</span><span style> </span><span style=3D"color:#008">const</span><=
span style=3D"color:#660">&,</span><span style> </span><span style=3D"c=
olor:#606">Trash</span><span style> </span><span style=3D"color:#008">const=
</span><span style=3D"color:#660">&)</span><span style> <br>
</span><span style=3D"color:#660">{</span><span style> <br>=A0 </span><span=
style=3D"color:#008">return</span><span style> </span><span style=3D"color=
:#008">true</span><span style=3D"color:#660">;</span><span style> <br></spa=
n><span style=3D"color:#660">}</span><span style><br>
<br></span><span style=3D"color:#008">template</span><span style> </span><s=
pan style=3D"color:#660"><</span><span style=3D"color:#008">class</span>=
<span style> T</span><span style=3D"color:#660">></span><span style> =A0=
=A0 =A0 =A0</span><span style=3D"color:#800">// no constexpr</span><span s=
tyle><br>
</span><span style=3D"color:#008">bool</span><span style> equal_impl</span>=
<span style=3D"color:#660">(</span><span style>T </span><span style=3D"colo=
r:#008">const</span><span style=3D"color:#660">&</span><span style> x</=
span><span style=3D"color:#660">,</span><span style> T </span><span style=
=3D"color:#008">const</span><span style=3D"color:#660">&</span><span st=
yle> y</span><span style=3D"color:#660">)</span><span style> <br>
</span><span style=3D"color:#660">{</span><span style> <br>=A0 doSomethingA=
tRuntime</span><span style=3D"color:#660">();</span><span style><br>=A0 </s=
pan><span style=3D"color:#008">return</span><span style> x </span><span sty=
le=3D"color:#660">=3D=3D</span><span style> y</span><span style=3D"color:#6=
60">;</span><span style><br>
</span><span style=3D"color:#660">}</span><span style><br><br></span></div>=
<span style=3D"color:#008">template</span><span style> </span><span style=
=3D"color:#660"><</span><span style=3D"color:#008">class</span><span sty=
le> T</span><span style=3D"color:#660">></span><div class=3D"im">
<span style><br></span><span style=3D"color:#008">constexpr</span><span sty=
le> </span><span style=3D"color:#008">bool</span><span style> equal</span><=
span style=3D"color:#660">(</span><span style>T </span><span style=3D"color=
:#008">const</span><span style=3D"color:#660">&</span><span style> x</s=
pan><span style=3D"color:#660">,</span><span style> T </span><span style=3D=
"color:#008">const</span><span style=3D"color:#660">&</span><span style=
> y</span><span style=3D"color:#660">)</span><span style> <br>
</span><span style=3D"color:#660">{</span><span style> <br>=A0 </span><span=
style=3D"color:#008">return</span><span style> equal_impl</span><span styl=
e=3D"color:#660">(</span><span style>x</span><span style=3D"color:#660">,</=
span><span style> y</span><span style=3D"color:#660">);</span><span style> =
<br>
</span><span style=3D"color:#660">}</span></div></div></code></div>=A0<br>S=
atisfies the following formal requirements:<br><br><br><span style=3D"font-=
family:courier new,monospace">template <class T></span><br><span styl=
e=3D"font-family:courier new,monospace">=A0 constexpr bool equal(const T&am=
p; x, const T& y);</span><br>
<br>=A0 =A0 =A0 =A0 <i>Returns:=A0 </i><span style=3D"font-family:courier n=
ew,monospace">x =3D=3D y</span>.<span class=3D"HOEnZb"><font color=3D"#8888=
88"><br></font></span></div><span class=3D"HOEnZb"><font color=3D"#888888">
<p></p>
-- <br>
=A0<br>
=A0<br>
=A0<br>
</font></span></blockquote></div>From my reading of the specification for t=
he constexpr, I would argue that such an implementation is not conforming b=
ecause it fails to produce a constant expression even if the arguments are =
constant expressions.<br>
<br>I understand your concern and my suggestion was based on the principle =
of following what the rest of the std is doing in some places I've look=
ed.<br><br>OTOH, this class is a bit distinct because the engaged state par=
ticipates in the production of the resulting constant expression, but that =
is not a constant expression itself.<br>
<br>Based on the responses from Daniel Krugler and Richard Smith, I think t=
hat some wording to better formalize the expected behavior might be in plac=
e. I'll look around in the std to see what's the best we can say.<b=
r>
<br clear=3D"all"><br>-- <br>Fernando Cacciola<br>SciSoft Consulting, Found=
er<br><a href=3D"http://www.scisoft-consulting.com">http://www.scisoft-cons=
ulting.com</a><br>
</div>
<p></p>
-- <br />
<br />
<br />
<br />
--047d7b621df80c7df404cf7ddc49--
.
Author: Fernando Cacciola <fernando.cacciola@gmail.com>
Date: Tue, 27 Nov 2012 15:08:16 -0300
Raw View
--e89a8f923f3a94052704cf7df188
Content-Type: text/plain; charset=ISO-8859-1
> But, the program becomes ill-formed at the point the function is in such a
>> way. The function definition is OK and allows for the first example.
>>
>
> I just want to add one comment here. Your analysis and Ville's comment
> might have risen an expectation that std::optional would be checking for
> being disengaged at compile-time when its contained value is read. While
> this is possible (I tried to explain the technique here<http://akrzemi1.wordpress.com/2011/05/06/compile-time-computations/>),
> this will not be the case for std::optional. At least it is not proposed
> right now.
>
Absolutely.
Good you clarified that.
> Such error handling mechanism in constexpr functions which works both at
> compile-time and run-time would require a run-time check for being engaged:
>
> // NOT PROPOSED!
>
> // precondition: this->is_engaged()
> constexpr T const& optional<T>::operator*()
> {
> return is_engaged() ? // unnecessary run-time cost
> contained_value() :
> throw logic_error("");
> }
>
> This would be an unacceptable cost in a C++ component, given that we
> already require as precondition that the optional object is engaged. As a
> consequence, you will be able to get the contained value of optional at
> compile-time, but at your own risk: you have to check yourself if it is
> engaged:
>
> constexpr oprional<int> oi = nullopt;
> int array[ *oi ]; // compiles, but will cause UB
>
>
> This is off the top of my head but the constexpr constructor would require
an explicit initialization for the underlying value, otherwise "oi" will
not be a constexpr object and its usage on the array would fail to compile.
--
Fernando Cacciola
SciSoft Consulting, Founder
http://www.scisoft-consulting.com
--
--e89a8f923f3a94052704cf7df188
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div class=3D"gmail_extra"><div class=3D"gmail_quote"><br><blockquote class=
=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padd=
ing-left:1ex"><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-le=
ft:0.8ex;border-left:1px #ccc solid;padding-left:1ex">
<div><div class=3D"gmail_quote"><div><div class=3D"h5"><div>But, the progra=
m becomes ill-formed at the point the function is in such a way. The functi=
on definition is OK and allows for the first example.<br></div></div></div>
</div></div></blockquote><div><br>I just want to add one comment here. Your=
analysis and Ville's comment might have risen an expectation that std:=
:optional would be checking for being disengaged at compile-time when its c=
ontained value is read. While this is possible (I tried to explain the tech=
nique <a href=3D"http://akrzemi1.wordpress.com/2011/05/06/compile-time-comp=
utations/" target=3D"_blank">here</a>), this will not be the case for std::=
optional. At least it is not proposed right now. </div>
</blockquote><div><br>Absolutely.<br>Good you clarified that.<br>=A0<br></d=
iv><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left=
:1px #ccc solid;padding-left:1ex"><div>Such error handling mechanism in con=
stexpr functions which works both at compile-time and run-time would requir=
e a run-time check for being engaged:<br>
<br><div style=3D"background-color:rgb(250,250,250);border-color:rgb(187,18=
7,187);border-style:solid;border-width:1px;word-wrap:break-word"><code><div=
><span style=3D"color:#800">// NOT PROPOSED!</span><span style><br><br></sp=
an><span style=3D"color:#800">// precondition: this->is_engaged()</span>=
<span style><br>
</span><span style=3D"color:#008">constexpr</span><span style> T </span><sp=
an style=3D"color:#008">const</span><span style=3D"color:#660">&</span>=
<span style> optional</span><span style=3D"color:#660"><</span><span sty=
le>T</span><span style=3D"color:#660">>::</span><span style=3D"color:#00=
8">operator</span><span style=3D"color:#660">*()</span><span style><br>
</span><span style=3D"color:#660">{</span><span style><br>=A0 </span><span =
style=3D"color:#008">return</span><span style> is_engaged</span><span style=
=3D"color:#660">()</span><span style> </span><span style=3D"color:#660">?</=
span><span style> =A0 </span><span style=3D"color:#800">// unnecessary run-=
time cost</span><span style><br>
=A0 =A0 contained_value</span><span style=3D"color:#660">()</span><span sty=
le> </span><span style=3D"color:#660">:</span><span style><br>=A0 =A0 </spa=
n><span style=3D"color:#008">throw</span><span style> logic_error</span><sp=
an style=3D"color:#660">(</span><span style=3D"color:#080">""</sp=
an><span style=3D"color:#660">);</span><span style><br>
</span><span style=3D"color:#660">}</span><span style><br></span></div></co=
de></div><br>This would be an unacceptable cost in a C++ component, given t=
hat we already require as precondition that the optional object is engaged.=
As a consequence, you will be able to get the contained value of optional =
at compile-time, but at your own risk: you have to check yourself if it is =
engaged:<br>
<br><div style=3D"background-color:rgb(250,250,250);border-color:rgb(187,18=
7,187);border-style:solid;border-width:1px;word-wrap:break-word"><code><div=
><span style=3D"color:#008">constexpr</span><span style> oprional</span><sp=
an style=3D"color:#080"><int></span><span style> oi </span><span styl=
e=3D"color:#660">=3D</span><span style> nullopt</span><span style=3D"color:=
#660">;</span><span style><br>
</span><span style=3D"color:#008">int</span><span style> array</span><span =
style=3D"color:#660">[</span><span style> </span><span style=3D"color:#660"=
>*</span><span style>oi </span><span style=3D"color:#660">];</span><span st=
yle> </span><span style=3D"color:#800">// compiles</span><span style=3D"col=
or:#800">, but will cause UB</span><span class=3D"HOEnZb"><font color=3D"#8=
88888"><span style><br>
</span></font></span></div></code></div><span class=3D"HOEnZb"><font color=
=3D"#888888"><br><br></font></span></div></blockquote><div>This is off the =
top of my head but the constexpr constructor would require an explicit init=
ialization for the underlying value, otherwise "oi" will not be a=
constexpr object and its usage on the array would fail to compile.<br>
<br></div></div>-- <br>Fernando Cacciola<br>SciSoft Consulting, Founder<br>=
<a href=3D"http://www.scisoft-consulting.com">http://www.scisoft-consulting=
..com</a><br>
</div>
<p></p>
-- <br />
<br />
<br />
<br />
--e89a8f923f3a94052704cf7df188--
.
Author: =?UTF-8?Q?Andrzej_Krzemie=C5=84ski?= <akrzemi1@gmail.com>
Date: Wed, 28 Nov 2012 00:58:03 -0800 (PST)
Raw View
------=_Part_1574_3142961.1354093083752
Content-Type: text/plain; charset=ISO-8859-1
>
>> constexpr oprional<int> oi = nullopt;
>> int array[ *oi ]; // compiles, but will cause UB
>>
>>
>> This is off the top of my head but the constexpr constructor would
> require an explicit initialization for the underlying value, otherwise "oi"
> will not be a constexpr object and its usage on the array would fail to
> compile.
>
Definitely. Such compile-time use cases already work in the new reference
implementation, so we know that it is implementable and can demonstrate how
to do it. For the standardese, we will not require this explicitly, though.
We will only say that (1) optional is a literal type, (2) the constructor
template has to be declared with 'constexpr', (3) template's instantiations
shall render constexpr constructors; and we will let the implementations
figure out the solution.
Regards,
&rzej
--
------=_Part_1574_3142961.1354093083752
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<br><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex=
;border-left: 1px #ccc solid;padding-left: 1ex;"><div><div class=3D"gmail_q=
uote"><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-l=
eft:1px #ccc solid;padding-left:1ex"><div>
<br><div style=3D"background-color:rgb(250,250,250);border-color:rgb(187,18=
7,187);border-style:solid;border-width:1px;word-wrap:break-word"><code><div=
><span style=3D"color:#008">constexpr</span><span> oprional</span><span sty=
le=3D"color:#080"><int></span><span> oi </span><span style=3D"color:#=
660">=3D</span><span> nullopt</span><span style=3D"color:#660">;</span><spa=
n><br>
</span><span style=3D"color:#008">int</span><span> array</span><span style=
=3D"color:#660">[</span><span> </span><span style=3D"color:#660">*</span><s=
pan>oi </span><span style=3D"color:#660">];</span><span> </span><span style=
=3D"color:#800">// compiles</span><span style=3D"color:#800">, but will cau=
se UB</span><span><font color=3D"#888888"><span><br>
</span></font></span></div></code></div><span><font color=3D"#888888"><br><=
br></font></span></div></blockquote><div>This is off the top of my head but=
the constexpr constructor would require an explicit initialization for the=
underlying value, otherwise "oi" will not be a constexpr object and its us=
age on the array would fail to compile.<br></div></div></div></blockquote><=
div><br>Definitely. Such compile-time use cases already work in the new ref=
erence implementation, so we know that it is implementable and can demonstr=
ate how to do it. For the standardese, we will not require this explicitly,=
though. We will only say that (1) optional is a literal type, (2) the cons=
tructor template has to be declared with 'constexpr', (3) template's instan=
tiations shall render constexpr constructors; and we will let the implement=
ations figure out the solution.<br><br>Regards,<br>&rzej<br></div>
<p></p>
-- <br />
<br />
<br />
<br />
------=_Part_1574_3142961.1354093083752--
.
Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Wed, 28 Nov 2012 11:04:27 +0200
Raw View
On 28 November 2012 10:58, Andrzej Krzemie=C5=84ski <akrzemi1@gmail.com> wr=
ote:
>>> constexpr oprional<int> oi =3D nullopt;
>>> int array[ *oi ]; // compiles, but will cause UB
>> This is off the top of my head but the constexpr constructor would requi=
re
>> an explicit initialization for the underlying value, otherwise "oi" will=
not
>> be a constexpr object and its usage on the array would fail to compile.
> Definitely. Such compile-time use cases already work in the new reference
> implementation, so we know that it is implementable and can demonstrate h=
ow
> to do it. For the standardese, we will not require this explicitly, thoug=
h.
> We will only say that (1) optional is a literal type, (2) the constructor
> template has to be declared with 'constexpr', (3) template's instantiatio=
ns
> shall render constexpr constructors; and we will let the implementations
> figure out the solution.
So.. just to clarify, can I invoke operator* for a constexpr optional
so that operator* is also
constexpr?
--=20
.
Author: =?UTF-8?Q?Andrzej_Krzemie=C5=84ski?= <akrzemi1@gmail.com>
Date: Wed, 28 Nov 2012 01:44:04 -0800 (PST)
Raw View
------=_Part_259_21860515.1354095844943
Content-Type: text/plain; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable
W dniu =B6roda, 28 listopada 2012 10:04:27 UTC+1 u=BFytkownik Ville Voutila=
inen=20
napisa=B3:
>
> On 28 November 2012 10:58, Andrzej Krzemie=F1ski <akrz...@gmail.com<javas=
cript:>>=20
> wrote:=20
> >>> constexpr oprional<int> oi =3D nullopt;=20
> >>> int array[ *oi ]; // compiles, but will cause UB=20
> >> This is off the top of my head but the constexpr constructor would=20
> require=20
> >> an explicit initialization for the underlying value, otherwise "oi"=20
> will not=20
> >> be a constexpr object and its usage on the array would fail to compile=
..=20
> > Definitely. Such compile-time use cases already work in the new=20
> reference=20
> > implementation, so we know that it is implementable and can demonstrate=
=20
> how=20
> > to do it. For the standardese, we will not require this explicitly,=20
> though.=20
> > We will only say that (1) optional is a literal type, (2) the=20
> constructor=20
> > template has to be declared with 'constexpr', (3) template's=20
> instantiations=20
> > shall render constexpr constructors; and we will let the implementation=
s=20
> > figure out the solution.=20
>
> So.. just to clarify, can I invoke operator* for a constexpr optional=20
> so that operator* is also=20
> constexpr?=20
>
Yes, the following will be legal:
optional<int> oi {2};
static_assert(*oi =3D=3D 2, "must be 2");
int array[*oi];
Although you have to check yourself if the optional object is engaged.
=20
--=20
------=_Part_259_21860515.1354095844943
Content-Type: text/html; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable
<br><br>W dniu =B6roda, 28 listopada 2012 10:04:27 UTC+1 u=BFytkownik Ville=
Voutilainen napisa=B3:<blockquote class=3D"gmail_quote" style=3D"margin: 0=
;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On 28 N=
ovember 2012 10:58, Andrzej Krzemie=F1ski <<a href=3D"javascript:" targe=
t=3D"_blank" gdf-obfuscated-mailto=3D"IrvNaEzSJBYJ">akrz...@gmail.com</a>&g=
t; wrote:
<br>>>> constexpr oprional<int> oi =3D nullopt;
<br>>>> int array[ *oi ]; // compiles, but will cause UB
<br>>> This is off the top of my head but the constexpr constructor w=
ould require
<br>>> an explicit initialization for the underlying value, otherwise=
"oi" will not
<br>>> be a constexpr object and its usage on the array would fail to=
compile.
<br>> Definitely. Such compile-time use cases already work in the new re=
ference
<br>> implementation, so we know that it is implementable and can demons=
trate how
<br>> to do it. For the standardese, we will not require this explicitly=
, though.
<br>> We will only say that (1) optional is a literal type, (2) the cons=
tructor
<br>> template has to be declared with 'constexpr', (3) template's insta=
ntiations
<br>> shall render constexpr constructors; and we will let the implement=
ations
<br>> figure out the solution.
<br>
<br>So.. just to clarify, can I invoke operator* for a constexpr optional
<br>so that operator* is also
<br>constexpr?
<br></blockquote><div><br>Yes, the following will be legal:<br><br><div cla=
ss=3D"prettyprint" style=3D"background-color: rgb(250, 250, 250); border-co=
lor: rgb(187, 187, 187); border-style: solid; border-width: 1px; word-wrap:=
break-word;"><code class=3D"prettyprint"><div class=3D"subprettyprint"><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify">optional</span><span=
style=3D"color: #080;" class=3D"styled-by-prettify"><int></span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> oi </span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=3D"colo=
r: #066;" class=3D"styled-by-prettify">2</span><span style=3D"color: #660;"=
class=3D"styled-by-prettify">};</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br></span><span style=3D"color: #008;" class=3D"st=
yled-by-prettify">static_assert</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">(*</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify">oi </span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">=3D=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> </span><span style=3D"color: #066;" class=3D"styled-by-prettify">2</span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"co=
lor: #080;" class=3D"styled-by-prettify">"must be 2"</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">);</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #008;" c=
lass=3D"styled-by-prettify">int</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"> array</span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">[*</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify">oi</span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>];</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></s=
pan></div></code></div><br>Although you have to check yourself if the optio=
nal object is engaged.<br> <br></div>
<p></p>
-- <br />
<br />
<br />
<br />
------=_Part_259_21860515.1354095844943--
.
Author: =?UTF-8?Q?Andrzej_Krzemie=C5=84ski?= <akrzemi1@gmail.com>
Date: Thu, 29 Nov 2012 14:09:48 -0800 (PST)
Raw View
------=_Part_419_16448101.1354226988437
Content-Type: text/plain; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable
W dniu =B6roda, 28 listopada 2012 10:44:04 UTC+1 u=BFytkownik Andrzej=20
Krzemie=F1ski napisa=B3:
>
>
>
> W dniu =B6roda, 28 listopada 2012 10:04:27 UTC+1 u=BFytkownik Ville=20
> Voutilainen napisa=B3:
>>
>> On 28 November 2012 10:58, Andrzej Krzemie=F1ski <akrz...@gmail.com>=20
>> wrote:=20
>> >>> constexpr oprional<int> oi =3D nullopt;=20
>> >>> int array[ *oi ]; // compiles, but will cause UB=20
>> >> This is off the top of my head but the constexpr constructor would=20
>> require=20
>> >> an explicit initialization for the underlying value, otherwise "oi"=
=20
>> will not=20
>> >> be a constexpr object and its usage on the array would fail to=20
>> compile.=20
>> > Definitely. Such compile-time use cases already work in the new=20
>> reference=20
>> > implementation, so we know that it is implementable and can demonstrat=
e=20
>> how=20
>> > to do it. For the standardese, we will not require this explicitly,=20
>> though.=20
>> > We will only say that (1) optional is a literal type, (2) the=20
>> constructor=20
>> > template has to be declared with 'constexpr', (3) template's=20
>> instantiations=20
>> > shall render constexpr constructors; and we will let the=20
>> implementations=20
>> > figure out the solution.=20
>>
>> So.. just to clarify, can I invoke operator* for a constexpr optional=20
>> so that operator* is also=20
>> constexpr?=20
>>
>
> Yes, the following will be legal:
>
> optional<int> oi {2};
> static_assert(*oi =3D=3D 2, "must be 2");
> int array[*oi];
>
> Although you have to check yourself if the optional object is engaged.
>
On the other hand, now when I play with the reference implementation, GCC=
=20
4.7.2 fails to compile the following (erroneous) code:
constexpr std::experimental::optional<int> oi{};
constexpr int i =3D *oi;
Saying: error: accessing=20
'std::experimental::constexpr_storage_t<int>::value_' member instead of=20
initialized 'std::experimental::constexpr_storage_t<int>::dummy_' member in=
=20
constant expression
This means compile-time observer functions work and we get compile-time=20
error checking for free. I am not sure if this is mandated by the Standard=
=20
or just a bonus from GCC. (You can find the reference implementation (still=
=20
in development) here<https://github.com/akrzemi1/Optional/blob/master/optio=
nal.hpp>
..)
Regards,
&rzej
--=20
------=_Part_419_16448101.1354226988437
Content-Type: text/html; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable
<br><br>W dniu =B6roda, 28 listopada 2012 10:44:04 UTC+1 u=BFytkownik Andrz=
ej Krzemie=F1ski napisa=B3:<blockquote class=3D"gmail_quote" style=3D"margi=
n: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><br=
><br>W dniu =B6roda, 28 listopada 2012 10:04:27 UTC+1 u=BFytkownik Ville Vo=
utilainen napisa=B3:<blockquote class=3D"gmail_quote" style=3D"margin:0;mar=
gin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex">On 28 November =
2012 10:58, Andrzej Krzemie=F1ski <<a>akrz...@gmail.com</a>> wrote:
<br>>>> constexpr oprional<int> oi =3D nullopt;
<br>>>> int array[ *oi ]; // compiles, but will cause UB
<br>>> This is off the top of my head but the constexpr constructor w=
ould require
<br>>> an explicit initialization for the underlying value, otherwise=
"oi" will not
<br>>> be a constexpr object and its usage on the array would fail to=
compile.
<br>> Definitely. Such compile-time use cases already work in the new re=
ference
<br>> implementation, so we know that it is implementable and can demons=
trate how
<br>> to do it. For the standardese, we will not require this explicitly=
, though.
<br>> We will only say that (1) optional is a literal type, (2) the cons=
tructor
<br>> template has to be declared with 'constexpr', (3) template's insta=
ntiations
<br>> shall render constexpr constructors; and we will let the implement=
ations
<br>> figure out the solution.
<br>
<br>So.. just to clarify, can I invoke operator* for a constexpr optional
<br>so that operator* is also
<br>constexpr?
<br></blockquote><div><br>Yes, the following will be legal:<br><br><div sty=
le=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,187);borde=
r-style:solid;border-width:1px;word-wrap:break-word"><code><div><span style=
=3D"color:#000">optional</span><span style=3D"color:#080"><int></span=
><span style=3D"color:#000"> oi </span><span style=3D"color:#660">{</span><=
span style=3D"color:#066">2</span><span style=3D"color:#660">};</span><span=
style=3D"color:#000"><br></span><span style=3D"color:#008">static_assert</=
span><span style=3D"color:#660">(*</span><span style=3D"color:#000">oi </sp=
an><span style=3D"color:#660">=3D=3D</span><span style=3D"color:#000"> </sp=
an><span style=3D"color:#066">2</span><span style=3D"color:#660">,</span><s=
pan style=3D"color:#000"> </span><span style=3D"color:#080">"must be 2"</sp=
an><span style=3D"color:#660">);</span><span style=3D"color:#000"><br></spa=
n><span style=3D"color:#008">int</span><span style=3D"color:#000"> array</s=
pan><span style=3D"color:#660">[*</span><span style=3D"color:#000">oi</span=
><span style=3D"color:#660">];</span><span style=3D"color:#000"><br></span>=
</div></code></div><br>Although you have to check yourself if the optional =
object is engaged.<br></div></blockquote><div><br>On the other hand, now wh=
en I play with the reference implementation, GCC 4.7.2 fails to compile the=
following (erroneous) code:<br><br><div class=3D"prettyprint" style=3D"bac=
kground-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187); border=
-style: solid; border-width: 1px; word-wrap: break-word;"><code class=3D"pr=
ettyprint"><div class=3D"subprettyprint"><span style=3D"color: #008;" class=
=3D"styled-by-prettify">constexpr</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> std</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">::</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify">experimental</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">::</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy">optional</span><span style=3D"color: #080;" class=3D"styled-by-prettify=
"><int></span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"> oi</span><span style=3D"color: #660;" class=3D"styled-by-prettify">{};<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span>=
<span style=3D"color: #008;" class=3D"styled-by-prettify">constexpr</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span styl=
e=3D"color: #008;" class=3D"styled-by-prettify">int</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> i </span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">*</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify">oi</span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></sp=
an></div></code></div><br>Saying: <span style=3D"font-family: courier new,m=
onospace;">error: accessing=20
'std::experimental::constexpr_storage_t<int>::value_' member=20
instead of initialized=20
'std::experimental::constexpr_storage_t<int>::dummy_' member in const=
ant expression</span><br><br>This means compile-time observer functions wor=
k and we get compile-time error checking for free. I am not sure if this is=
mandated by the Standard or just a bonus from GCC. (You can find the refer=
ence implementation (still in development) <a href=3D"https://github.com/ak=
rzemi1/Optional/blob/master/optional.hpp">here</a>.)<br><br>Regards,<br>&am=
p;rzej<br><br><br></div>
<p></p>
-- <br />
<br />
<br />
<br />
------=_Part_419_16448101.1354226988437--
.
Author: =?ISO-8859-1?Q?Daniel_Kr=FCgler?= <daniel.kruegler@gmail.com>
Date: Thu, 29 Nov 2012 23:14:47 +0100
Raw View
--bcaec517a9906bc61004cfa99c70
Content-Type: text/plain; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable
2012/11/29 Andrzej Krzemie=F1ski <akrzemi1@gmail.com>
>
>
> W dniu =B6roda, 28 listopada 2012 10:44:04 UTC+1 u=BFytkownik Andrzej
> Krzemie=F1ski napisa=B3:
>
>>
>>
>> W dniu =B6roda, 28 listopada 2012 10:04:27 UTC+1 u=BFytkownik Ville
>> Voutilainen napisa=B3:
>>>
>>> On 28 November 2012 10:58, Andrzej Krzemie=F1ski <akrz...@gmail.com>
>>> wrote:
>>> >>> constexpr oprional<int> oi =3D nullopt;
>>> >>> int array[ *oi ]; // compiles, but will cause UB
>>> >> This is off the top of my head but the constexpr constructor would
>>> require
>>> >> an explicit initialization for the underlying value, otherwise "oi"
>>> will not
>>> >> be a constexpr object and its usage on the array would fail to
>>> compile.
>>> > Definitely. Such compile-time use cases already work in the new
>>> reference
>>> > implementation, so we know that it is implementable and can
>>> demonstrate how
>>> > to do it. For the standardese, we will not require this explicitly,
>>> though.
>>> > We will only say that (1) optional is a literal type, (2) the
>>> constructor
>>> > template has to be declared with 'constexpr', (3) template's
>>> instantiations
>>> > shall render constexpr constructors; and we will let the
>>> implementations
>>> > figure out the solution.
>>>
>>> So.. just to clarify, can I invoke operator* for a constexpr optional
>>> so that operator* is also
>>> constexpr?
>>>
>>
>> Yes, the following will be legal:
>>
>> optional<int> oi {2};
>> static_assert(*oi =3D=3D 2, "must be 2");
>> int array[*oi];
>>
>> Although you have to check yourself if the optional object is engaged.
>>
>
> On the other hand, now when I play with the reference implementation, GCC
> 4.7.2 fails to compile the following (erroneous) code:
>
> constexpr std::experimental::optional<int> oi{};
> constexpr int i =3D *oi;
>
> Saying: error: accessing
> 'std::experimental::constexpr_storage_t<int>::value_' member instead of
> initialized 'std::experimental::constexpr_storage_t<int>::dummy_' member =
in
> constant expression
>
> This means compile-time observer functions work and we get compile-time
> error checking for free. I am not sure if this is mandated by the Standar=
d
> or just a bonus from GCC. (You can find the reference implementation (sti=
ll
> in development) here<https://github.com/akrzemi1/Optional/blob/master/opt=
ional.hpp>
> .)
>
The behaviour is required by [expr.const] p2:
"an operation that would have undefined behavior"
This means that an implementation has to realize whether all read objects
as part of the constant expression have indeed welldefined values.
- Daniel
--=20
--bcaec517a9906bc61004cfa99c70
Content-Type: text/html; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable
<div class=3D"gmail_quote">2012/11/29 Andrzej Krzemie=F1ski <span dir=3D"lt=
r"><<a href=3D"mailto:akrzemi1@gmail.com" target=3D"_blank">akrzemi1@gma=
il.com</a>></span><br><blockquote class=3D"gmail_quote" style=3D"margin:=
0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br><br>W dniu =B6roda, 28 listopada 2012 10:44:04 UTC+1 u=BFytkownik Andrz=
ej Krzemie=F1ski napisa=B3:<div><div class=3D"h5"><blockquote class=3D"gmai=
l_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;pad=
ding-left:1ex">
<br><br>W dniu =B6roda, 28 listopada 2012 10:04:27 UTC+1 u=BFytkownik Ville=
Voutilainen napisa=B3:<blockquote class=3D"gmail_quote" style=3D"margin:0;=
margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex">On 28 Novemb=
er 2012 10:58, Andrzej Krzemie=F1ski <<a>akrz...@gmail.com</a>> wrote=
:
<br>>>> constexpr oprional<int> oi =3D nullopt;
<br>>>> int array[ *oi ]; // compiles, but will cause UB
<br>>> This is off the top of my head but the constexpr constructor w=
ould require
<br>>> an explicit initialization for the underlying value, otherwise=
"oi" will not
<br>>> be a constexpr object and its usage on the array would fail to=
compile.
<br>> Definitely. Such compile-time use cases already work in the new re=
ference
<br>> implementation, so we know that it is implementable and can demons=
trate how
<br>> to do it. For the standardese, we will not require this explicitly=
, though.
<br>> We will only say that (1) optional is a literal type, (2) the cons=
tructor
<br>> template has to be declared with 'constexpr', (3) template=
's instantiations
<br>> shall render constexpr constructors; and we will let the implement=
ations
<br>> figure out the solution.
<br>
<br>So.. just to clarify, can I invoke operator* for a constexpr optional
<br>so that operator* is also
<br>constexpr?
<br></blockquote><div><br>Yes, the following will be legal:<br><br><div sty=
le=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,187);borde=
r-style:solid;border-width:1px;word-wrap:break-word"><code><div><span style=
>optional</span><span style=3D"color:#080"><int></span><span style> o=
i </span><span style=3D"color:#660">{</span><span style=3D"color:#066">2</s=
pan><span style=3D"color:#660">};</span><span style><br>
</span><span style=3D"color:#008">static_assert</span><span style=3D"color:=
#660">(*</span><span style>oi </span><span style=3D"color:#660">=3D=3D</spa=
n><span style> </span><span style=3D"color:#066">2</span><span style=3D"col=
or:#660">,</span><span style> </span><span style=3D"color:#080">"must =
be 2"</span><span style=3D"color:#660">);</span><span style><br>
</span><span style=3D"color:#008">int</span><span style> array</span><span =
style=3D"color:#660">[*</span><span style>oi</span><span style=3D"color:#66=
0">];</span><span style><br></span></div></code></div><br>Although you have=
to check yourself if the optional object is engaged.<br>
</div></blockquote></div></div><div><br>On the other hand, now when I play =
with the reference implementation, GCC 4.7.2 fails to compile the following=
(erroneous) code:<br><br><div style=3D"background-color:rgb(250,250,250);b=
order-color:rgb(187,187,187);border-style:solid;border-width:1px;word-wrap:=
break-word">
<code><div><span style=3D"color:#008">constexpr</span><span style> std</spa=
n><span style=3D"color:#660">::</span><span style>experimental</span><span =
style=3D"color:#660">::</span><span style>optional</span><span style=3D"col=
or:#080"><int></span><span style> oi</span><span style=3D"color:#660"=
>{};</span><span style><br>
</span><span style=3D"color:#008">constexpr</span><span style> </span><span=
style=3D"color:#008">int</span><span style> i </span><span style=3D"color:=
#660">=3D</span><span style> </span><span style=3D"color:#660">*</span><spa=
n style>oi</span><span style=3D"color:#660">;</span><span style><br>
</span></div></code></div><br>Saying: <span style=3D"font-family:courier ne=
w,monospace">error: accessing=20
'std::experimental::constexpr_storage_t<int>::value_' member=
=20
instead of initialized=20
'std::experimental::constexpr_storage_t<int>::dummy_' member =
in constant expression</span><br><br>This means compile-time observer funct=
ions work and we get compile-time error checking for free. I am not sure if=
this is mandated by the Standard or just a bonus from GCC. (You can find t=
he reference implementation (still in development) <a href=3D"https://githu=
b.com/akrzemi1/Optional/blob/master/optional.hpp" target=3D"_blank">here</a=
>.)<br>
</div></blockquote></div><br>The behaviour is required by [expr.const] p2:<=
br><br>"an operation that would have undefined behavior"<br><br>T=
his means that an implementation has to realize whether all read objects as=
part of the constant expression have indeed welldefined values. <br>
<br>- Daniel<br><br>
<p></p>
-- <br />
<br />
<br />
<br />
--bcaec517a9906bc61004cfa99c70--
.
Author: Richard Smith <richard@metafoo.co.uk>
Date: Thu, 29 Nov 2012 14:24:37 -0800
Raw View
--bcaec555557c99c1f904cfa9bf55
Content-Type: text/plain; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable
On Thu, Nov 29, 2012 at 2:14 PM, Daniel Kr=FCgler
<daniel.kruegler@gmail.com>wrote:
> 2012/11/29 Andrzej Krzemie=F1ski <akrzemi1@gmail.com>
>
>>
>>
>> W dniu =B6roda, 28 listopada 2012 10:44:04 UTC+1 u=BFytkownik Andrzej
>> Krzemie=F1ski napisa=B3:
>>
>>>
>>>
>>> W dniu =B6roda, 28 listopada 2012 10:04:27 UTC+1 u=BFytkownik Ville
>>> Voutilainen napisa=B3:
>>>>
>>>> On 28 November 2012 10:58, Andrzej Krzemie=F1ski <akrz...@gmail.com>
>>>> wrote:
>>>> >>> constexpr oprional<int> oi =3D nullopt;
>>>> >>> int array[ *oi ]; // compiles, but will cause UB
>>>> >> This is off the top of my head but the constexpr constructor would
>>>> require
>>>> >> an explicit initialization for the underlying value, otherwise "oi"
>>>> will not
>>>> >> be a constexpr object and its usage on the array would fail to
>>>> compile.
>>>> > Definitely. Such compile-time use cases already work in the new
>>>> reference
>>>> > implementation, so we know that it is implementable and can
>>>> demonstrate how
>>>> > to do it. For the standardese, we will not require this explicitly,
>>>> though.
>>>> > We will only say that (1) optional is a literal type, (2) the
>>>> constructor
>>>> > template has to be declared with 'constexpr', (3) template's
>>>> instantiations
>>>> > shall render constexpr constructors; and we will let the
>>>> implementations
>>>> > figure out the solution.
>>>>
>>>> So.. just to clarify, can I invoke operator* for a constexpr optional
>>>> so that operator* is also
>>>> constexpr?
>>>>
>>>
>>> Yes, the following will be legal:
>>>
>>> optional<int> oi {2};
>>> static_assert(*oi =3D=3D 2, "must be 2");
>>> int array[*oi];
>>>
>>> Although you have to check yourself if the optional object is engaged.
>>>
>>
>> On the other hand, now when I play with the reference implementation, GC=
C
>> 4.7.2 fails to compile the following (erroneous) code:
>>
>> constexpr std::experimental::optional<int> oi{};
>> constexpr int i =3D *oi;
>>
>> Saying: error: accessing
>> 'std::experimental::constexpr_storage_t<int>::value_' member instead of
>> initialized 'std::experimental::constexpr_storage_t<int>::dummy_' member=
in
>> constant expression
>>
>> This means compile-time observer functions work and we get compile-time
>> error checking for free. I am not sure if this is mandated by the Standa=
rd
>> or just a bonus from GCC. (You can find the reference implementation (st=
ill
>> in development) here<https://github.com/akrzemi1/Optional/blob/master/op=
tional.hpp>
>> .)
>>
>
> The behaviour is required by [expr.const] p2:
>
> "an operation that would have undefined behavior"
>
> This means that an implementation has to realize whether all read objects
> as part of the constant expression have indeed welldefined values.
>
This particular case is also explicitly called out:
"an lvalue-to-rvalue conversion (4.1) that is applied to a glvalue that
refers to a non-active member of a union or a subobject thereof;"
(The common initial subsequence rule for unions does not apply during
constant expression evaluation.)
--=20
--bcaec555557c99c1f904cfa9bf55
Content-Type: text/html; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable
On Thu, Nov 29, 2012 at 2:14 PM, Daniel Kr=FCgler <span dir=3D"ltr"><<a =
href=3D"mailto:daniel.kruegler@gmail.com" target=3D"_blank">daniel.kruegler=
@gmail.com</a>></span> wrote:<br><div class=3D"gmail_quote"><blockquote =
class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid=
;padding-left:1ex">
<div class=3D"HOEnZb"><div class=3D"h5"><div class=3D"gmail_quote">2012/11/=
29 Andrzej Krzemie=F1ski <span dir=3D"ltr"><<a href=3D"mailto:akrzemi1@g=
mail.com" target=3D"_blank">akrzemi1@gmail.com</a>></span><br><blockquot=
e class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc sol=
id;padding-left:1ex">
<br><br>W dniu =B6roda, 28 listopada 2012 10:44:04 UTC+1 u=BFytkownik Andrz=
ej Krzemie=F1ski napisa=B3:<div><div><blockquote class=3D"gmail_quote" styl=
e=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex=
">
<br><br>W dniu =B6roda, 28 listopada 2012 10:04:27 UTC+1 u=BFytkownik Ville=
Voutilainen napisa=B3:<blockquote class=3D"gmail_quote" style=3D"margin:0;=
margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex">On 28 Novemb=
er 2012 10:58, Andrzej Krzemie=F1ski <<a>akrz...@gmail.com</a>> wrote=
:
<br>>>> constexpr oprional<int> oi =3D nullopt;
<br>>>> int array[ *oi ]; // compiles, but will cause UB
<br>>> This is off the top of my head but the constexpr constructor w=
ould require
<br>>> an explicit initialization for the underlying value, otherwise=
"oi" will not
<br>>> be a constexpr object and its usage on the array would fail to=
compile.
<br>> Definitely. Such compile-time use cases already work in the new re=
ference
<br>> implementation, so we know that it is implementable and can demons=
trate how
<br>> to do it. For the standardese, we will not require this explicitly=
, though.
<br>> We will only say that (1) optional is a literal type, (2) the cons=
tructor
<br>> template has to be declared with 'constexpr', (3) template=
's instantiations
<br>> shall render constexpr constructors; and we will let the implement=
ations
<br>> figure out the solution.
<br>
<br>So.. just to clarify, can I invoke operator* for a constexpr optional
<br>so that operator* is also
<br>constexpr?
<br></blockquote><div><br>Yes, the following will be legal:<br><br><div sty=
le=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,187);borde=
r-style:solid;border-width:1px;word-wrap:break-word"><code><div><span>optio=
nal</span><span style=3D"color:#080"><int></span><span> oi </span><sp=
an style=3D"color:#660">{</span><span style=3D"color:#066">2</span><span st=
yle=3D"color:#660">};</span><span><br>
</span><span style=3D"color:#008">static_assert</span><span style=3D"color:=
#660">(*</span><span>oi </span><span style=3D"color:#660">=3D=3D</span><spa=
n> </span><span style=3D"color:#066">2</span><span style=3D"color:#660">,</=
span><span> </span><span style=3D"color:#080">"must be 2"</span><=
span style=3D"color:#660">);</span><span><br>
</span><span style=3D"color:#008">int</span><span> array</span><span style=
=3D"color:#660">[*</span><span>oi</span><span style=3D"color:#660">];</span=
><span><br></span></div></code></div><br>Although you have to check yoursel=
f if the optional object is engaged.<br>
</div></blockquote></div></div><div><br>On the other hand, now when I play =
with the reference implementation, GCC 4.7.2 fails to compile the following=
(erroneous) code:<br><br><div style=3D"background-color:rgb(250,250,250);b=
order-color:rgb(187,187,187);border-style:solid;border-width:1px;word-wrap:=
break-word">
<code><div><span style=3D"color:#008">constexpr</span><span> std</span><spa=
n style=3D"color:#660">::</span><span>experimental</span><span style=3D"col=
or:#660">::</span><span>optional</span><span style=3D"color:#080"><int&g=
t;</span><span> oi</span><span style=3D"color:#660">{};</span><span><br>
</span><span style=3D"color:#008">constexpr</span><span> </span><span style=
=3D"color:#008">int</span><span> i </span><span style=3D"color:#660">=3D</s=
pan><span> </span><span style=3D"color:#660">*</span><span>oi</span><span s=
tyle=3D"color:#660">;</span><span><br>
</span></div></code></div><br>Saying: <span style=3D"font-family:courier ne=
w,monospace">error: accessing=20
'std::experimental::constexpr_storage_t<int>::value_' member=
=20
instead of initialized=20
'std::experimental::constexpr_storage_t<int>::dummy_' member =
in constant expression</span><br><br>This means compile-time observer funct=
ions work and we get compile-time error checking for free. I am not sure if=
this is mandated by the Standard or just a bonus from GCC. (You can find t=
he reference implementation (still in development) <a href=3D"https://githu=
b.com/akrzemi1/Optional/blob/master/optional.hpp" target=3D"_blank">here</a=
>.)<br>
</div></blockquote></div><br></div></div>The behaviour is required by [expr=
..const] p2:<br><br>"an operation that would have undefined behavior&qu=
ot;<br><br>This means that an implementation has to realize whether all rea=
d objects as part of the constant expression have indeed welldefined values=
.. <br>
</blockquote><div><br></div><div>This particular case is also explicitly ca=
lled out:</div><div><br></div><div><div>"an lvalue-to-rvalue conversio=
n (4.1) that is applied to a glvalue that refers to a non-active member of =
a union or a subobject thereof;"</div>
</div><div><br></div><div>(The common initial subsequence rule for unions d=
oes not apply during constant expression evaluation.)</div></div>
<p></p>
-- <br />
<br />
<br />
<br />
--bcaec555557c99c1f904cfa9bf55--
.
Author: =?UTF-8?Q?Andrzej_Krzemie=C5=84ski?= <akrzemi1@gmail.com>
Date: Wed, 13 Feb 2013 23:30:23 -0800 (PST)
Raw View
------=_Part_120_3793231.1360827023160
Content-Type: text/plain; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable
W dniu =B6roda, 28 listopada 2012 09:58:03 UTC+1 u=BFytkownik Andrzej=20
Krzemie=F1ski napisa=B3:
>
>
>
>>> constexpr oprional<int> oi =3D nullopt;
>>> int array[ *oi ]; // compiles, but will cause UB
>>>
>>>
>>> This is off the top of my head but the constexpr constructor would=20
>> require an explicit initialization for the underlying value, otherwise "=
oi"=20
>> will not be a constexpr object and its usage on the array would fail to=
=20
>> compile.
>>
>
> Definitely. Such compile-time use cases already work in the new reference=
=20
> implementation, so we know that it is implementable and can demonstrate h=
ow=20
> to do it. For the standardese, we will not require this explicitly, thoug=
h.=20
> We will only say that (1) optional is a literal type, (2) the constructor=
=20
> template has to be declared with 'constexpr', (3) template's instantiatio=
ns=20
> shall render constexpr constructors; and we will let the implementations=
=20
> figure out the solution.
>
However, now that I started testing the reference implementation with Clang=
=20
3.2 it looks like implementing a constexpr operator-> is impossible. The=20
operator has to return an address to the contained value and there is no=20
way to implement a constexpr function addressof. I think we will have to=20
relax the requirements in the standardese: operator* must be constexpr, but=
=20
operator-> does not.
--=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/?hl=3Den.
------=_Part_120_3793231.1360827023160
Content-Type: text/html; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable
<br><br>W dniu =B6roda, 28 listopada 2012 09:58:03 UTC+1 u=BFytkownik Andrz=
ej Krzemie=F1ski napisa=B3:<blockquote class=3D"gmail_quote" style=3D"margi=
n: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><br=
><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;bord=
er-left:1px #ccc solid;padding-left:1ex"><div><div class=3D"gmail_quote"><b=
lockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px =
#ccc solid;padding-left:1ex"><div>
<br><div style=3D"background-color:rgb(250,250,250);border-color:rgb(187,18=
7,187);border-style:solid;border-width:1px;word-wrap:break-word"><code><div=
><span style=3D"color:#008">constexpr</span><span> oprional</span><span sty=
le=3D"color:#080"><int></span><span> oi </span><span style=3D"color:#=
660">=3D</span><span> nullopt</span><span style=3D"color:#660">;</span><spa=
n><br>
</span><span style=3D"color:#008">int</span><span> array</span><span style=
=3D"color:#660">[</span><span> </span><span style=3D"color:#660">*</span><s=
pan>oi </span><span style=3D"color:#660">];</span><span> </span><span style=
=3D"color:#800">// compiles</span><span style=3D"color:#800">, but will cau=
se UB</span><span><font color=3D"#888888"><span><br>
</span></font></span></div></code></div><span><font color=3D"#888888"><br><=
br></font></span></div></blockquote><div>This is off the top of my head but=
the constexpr constructor would require an explicit initialization for the=
underlying value, otherwise "oi" will not be a constexpr object and its us=
age on the array would fail to compile.<br></div></div></div></blockquote><=
div><br>Definitely. Such compile-time use cases already work in the new ref=
erence implementation, so we know that it is implementable and can demonstr=
ate how to do it. For the standardese, we will not require this explicitly,=
though. We will only say that (1) optional is a literal type, (2) the cons=
tructor template has to be declared with 'constexpr', (3) template's instan=
tiations shall render constexpr constructors; and we will let the implement=
ations figure out the solution.<br></div></blockquote><div><br>However, now=
that I started testing the reference implementation with Clang 3.2 it look=
s like implementing a constexpr operator-> is impossible. The operator h=
as to return an address to the contained value and there is no way to imple=
ment a constexpr function addressof. I think we will have to relax the requ=
irements in the standardese: operator* must be constexpr, but operator->=
does not.<br></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/?hl=3Den">http://groups.google.com/a/isocpp.org/group/std-pro=
posals/?hl=3Den</a>.<br />
<br />
<br />
------=_Part_120_3793231.1360827023160--
.
Author: Richard Smith <richard@metafoo.co.uk>
Date: Fri, 22 Feb 2013 16:26:23 -0800
Raw View
--089e0122a8968da91404d6595b36
Content-Type: text/plain; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable
On Wed, Feb 13, 2013 at 11:30 PM, Andrzej Krzemie=F1ski <akrzemi1@gmail.com=
>wrote:
>
>
> W dniu =B6roda, 28 listopada 2012 09:58:03 UTC+1 u=BFytkownik Andrzej
> Krzemie=F1ski napisa=B3:
>
>>
>>
>>>> constexpr oprional<int> oi =3D nullopt;
>>>> int array[ *oi ]; // compiles, but will cause UB
>>>>
>>>>
>>>> This is off the top of my head but the constexpr constructor would
>>> require an explicit initialization for the underlying value, otherwise =
"oi"
>>> will not be a constexpr object and its usage on the array would fail to
>>> compile.
>>>
>>
>> Definitely. Such compile-time use cases already work in the new referenc=
e
>> implementation, so we know that it is implementable and can demonstrate =
how
>> to do it. For the standardese, we will not require this explicitly, thou=
gh.
>> We will only say that (1) optional is a literal type, (2) the constructo=
r
>> template has to be declared with 'constexpr', (3) template's instantiati=
ons
>> shall render constexpr constructors; and we will let the implementations
>> figure out the solution.
>>
>
> However, now that I started testing the reference implementation with
> Clang 3.2 it looks like implementing a constexpr operator-> is impossible=
..
> The operator has to return an address to the contained value and there is
> no way to implement a constexpr function addressof. I think we will have =
to
> relax the requirements in the standardese: operator* must be constexpr, b=
ut
> operator-> does not.
>
You don't need to assume that the standard library must be implementable in
pure C++; that's certainly not true for all the type traits, for instance.
Instead, I suggest that you propose that 'addressof' is made constexpr, and
is required to produce an address constant expression if given a reference
constant expression. The implementation can use a builtin or similar to
make that work.
--=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/?hl=3Den.
--089e0122a8968da91404d6595b36
Content-Type: text/html; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable
On Wed, Feb 13, 2013 at 11:30 PM, Andrzej Krzemie=F1ski <span dir=3D"ltr">&=
lt;<a href=3D"mailto:akrzemi1@gmail.com" target=3D"_blank">akrzemi1@gmail.c=
om</a>></span> wrote:<br><div class=3D"gmail_quote"><blockquote class=3D=
"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding=
-left:1ex">
<br><br>W dniu =B6roda, 28 listopada 2012 09:58:03 UTC+1 u=BFytkownik Andrz=
ej Krzemie=F1ski napisa=B3:<div><div class=3D"h5"><blockquote class=3D"gmai=
l_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;pad=
ding-left:1ex">
<br><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;b=
order-left:1px #ccc solid;padding-left:1ex"><div><div class=3D"gmail_quote"=
><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1=
px #ccc solid;padding-left:1ex">
<div>
<br><div style=3D"background-color:rgb(250,250,250);border-color:rgb(187,18=
7,187);border-style:solid;border-width:1px;word-wrap:break-word"><code><div=
><span style=3D"color:#008">constexpr</span><span> oprional</span><span sty=
le=3D"color:#080"><int></span><span> oi </span><span style=3D"color:#=
660">=3D</span><span> nullopt</span><span style=3D"color:#660">;</span><spa=
n><br>
</span><span style=3D"color:#008">int</span><span> array</span><span style=
=3D"color:#660">[</span><span> </span><span style=3D"color:#660">*</span><s=
pan>oi </span><span style=3D"color:#660">];</span><span> </span><span style=
=3D"color:#800">// compiles</span><span style=3D"color:#800">, but will cau=
se UB</span><span><font color=3D"#888888"><span><br>
</span></font></span></div></code></div><span><font color=3D"#888888"><br><=
br></font></span></div></blockquote><div>This is off the top of my head but=
the constexpr constructor would require an explicit initialization for the=
underlying value, otherwise "oi" will not be a constexpr object =
and its usage on the array would fail to compile.<br>
</div></div></div></blockquote><div><br>Definitely. Such compile-time use c=
ases already work in the new reference implementation, so we know that it i=
s implementable and can demonstrate how to do it. For the standardese, we w=
ill not require this explicitly, though. We will only say that (1) optional=
is a literal type, (2) the constructor template has to be declared with &#=
39;constexpr', (3) template's instantiations shall render constexpr=
constructors; and we will let the implementations figure out the solution.=
<br>
</div></blockquote></div></div><div><br>However, now that I started testing=
the reference implementation with Clang 3.2 it looks like implementing a c=
onstexpr operator-> is impossible. The operator has to return an address=
to the contained value and there is no way to implement a constexpr functi=
on addressof. I think we will have to relax the requirements in the standar=
dese: operator* must be constexpr, but operator-> does not.</div>
</blockquote><div><br></div><div>You don't need to assume that the stan=
dard library must be implementable in pure C++; that's certainly not tr=
ue for all the type traits, for instance. Instead, I suggest that you propo=
se that 'addressof' is made constexpr, and is required to produce a=
n address constant expression if given a reference constant expression. The=
implementation can use a builtin or similar to make that work.</div>
</div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/?hl=3Den">http://groups.google.com/a/isocpp.org/group/std-pro=
posals/?hl=3Den</a>.<br />
<br />
<br />
--089e0122a8968da91404d6595b36--
.
Author: =?UTF-8?Q?Andrzej_Krzemie=C5=84ski?= <akrzemi1@gmail.com>
Date: Mon, 25 Feb 2013 01:07:48 -0800 (PST)
Raw View
------=_Part_1_705647.1361783268509
Content-Type: text/plain; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable
W dniu sobota, 23 lutego 2013 01:26:23 UTC+1 u=BFytkownik Richard Smith=20
napisa=B3:
>
> On Wed, Feb 13, 2013 at 11:30 PM, Andrzej Krzemie=F1ski <akrz...@gmail.co=
m<javascript:>
> > wrote:
>
>>
>>
>> W dniu =B6roda, 28 listopada 2012 09:58:03 UTC+1 u=BFytkownik Andrzej=20
>> Krzemie=F1ski napisa=B3:
>>
>>>
>>> =20
>>>>> constexpr oprional<int> oi =3D nullopt;
>>>>> int array[ *oi ]; // compiles, but will cause UB
>>>>>
>>>>>
>>>>> This is off the top of my head but the constexpr constructor would=20
>>>> require an explicit initialization for the underlying value, otherwise=
"oi"=20
>>>> will not be a constexpr object and its usage on the array would fail t=
o=20
>>>> compile.
>>>>
>>>
>>> Definitely. Such compile-time use cases already work in the new=20
>>> reference implementation, so we know that it is implementable and can=
=20
>>> demonstrate how to do it. For the standardese, we will not require this=
=20
>>> explicitly, though. We will only say that (1) optional is a literal typ=
e,=20
>>> (2) the constructor template has to be declared with 'constexpr', (3)=
=20
>>> template's instantiations shall render constexpr constructors; and we w=
ill=20
>>> let the implementations figure out the solution.
>>>
>>
>> However, now that I started testing the reference implementation with=20
>> Clang 3.2 it looks like implementing a constexpr operator-> is impossibl=
e.=20
>> The operator has to return an address to the contained value and there i=
s=20
>> no way to implement a constexpr function addressof. I think we will have=
to=20
>> relax the requirements in the standardese: operator* must be constexpr, =
but=20
>> operator-> does not.
>>
>
> You don't need to assume that the standard library must be implementable=
=20
> in pure C++; that's certainly not true for all the type traits, for=20
> instance. Instead, I suggest that you propose that 'addressof' is made=20
> constexpr, and is required to produce an address constant expression if=
=20
> given a reference constant expression. The implementation can use a built=
in=20
> or similar to make that work.
>
Having a constexpr addressof() is certainly the ideal. But (I think) since=
=20
it cannot be implemented in C++ it makes it a core language extension, and=
=20
requires that the proposal is processed by EWG. Our goal is to make=20
optional go into C++ library as soon as in 2014 (if this is possible) and=
=20
by adding language extensions we may be unnecessarily making the process=20
longer. In our proposal, implementations are not forbidden to offer this=20
additional feature, and the feature can also be added seamlessly into the=
=20
future revisions of C++.
Regards,
&rzej
--=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/?hl=3Den.
------=_Part_1_705647.1361783268509
Content-Type: text/html; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable
<br><br>W dniu sobota, 23 lutego 2013 01:26:23 UTC+1 u=BFytkownik Richard S=
mith napisa=B3:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-=
left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On Wed, Feb 13,=
2013 at 11:30 PM, Andrzej Krzemie=F1ski <span dir=3D"ltr"><<a href=3D"j=
avascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"e2Q4ltg8HwEJ">akrz..=
..@gmail.com</a>></span> wrote:<br><div class=3D"gmail_quote"><blockquote=
class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc soli=
d;padding-left:1ex">
<br><br>W dniu =B6roda, 28 listopada 2012 09:58:03 UTC+1 u=BFytkownik Andrz=
ej Krzemie=F1ski napisa=B3:<div><div><blockquote class=3D"gmail_quote" styl=
e=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex=
">
<br><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;b=
order-left:1px #ccc solid;padding-left:1ex"><div><div class=3D"gmail_quote"=
><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1=
px #ccc solid;padding-left:1ex">
<div>
<br><div style=3D"background-color:rgb(250,250,250);border-color:rgb(187,18=
7,187);border-style:solid;border-width:1px;word-wrap:break-word"><code><div=
><span style=3D"color:#008">constexpr</span><span> oprional</span><span sty=
le=3D"color:#080"><int></span><span> oi </span><span style=3D"color:#=
660">=3D</span><span> nullopt</span><span style=3D"color:#660">;</span><spa=
n><br>
</span><span style=3D"color:#008">int</span><span> array</span><span style=
=3D"color:#660">[</span><span> </span><span style=3D"color:#660">*</span><s=
pan>oi </span><span style=3D"color:#660">];</span><span> </span><span style=
=3D"color:#800">// compiles</span><span style=3D"color:#800">, but will cau=
se UB</span><span><font color=3D"#888888"><span><br>
</span></font></span></div></code></div><span><font color=3D"#888888"><br><=
br></font></span></div></blockquote><div>This is off the top of my head but=
the constexpr constructor would require an explicit initialization for the=
underlying value, otherwise "oi" will not be a constexpr object and its us=
age on the array would fail to compile.<br>
</div></div></div></blockquote><div><br>Definitely. Such compile-time use c=
ases already work in the new reference implementation, so we know that it i=
s implementable and can demonstrate how to do it. For the standardese, we w=
ill not require this explicitly, though. We will only say that (1) optional=
is a literal type, (2) the constructor template has to be declared with 'c=
onstexpr', (3) template's instantiations shall render constexpr constructor=
s; and we will let the implementations figure out the solution.<br>
</div></blockquote></div></div><div><br>However, now that I started testing=
the reference implementation with Clang 3.2 it looks like implementing a c=
onstexpr operator-> is impossible. The operator has to return an address=
to the contained value and there is no way to implement a constexpr functi=
on addressof. I think we will have to relax the requirements in the standar=
dese: operator* must be constexpr, but operator-> does not.</div>
</blockquote><div><br></div><div>You don't need to assume that the standard=
library must be implementable in pure C++; that's certainly not true for a=
ll the type traits, for instance. Instead, I suggest that you propose that =
'addressof' is made constexpr, and is required to produce an address consta=
nt expression if given a reference constant expression. The implementation =
can use a builtin or similar to make that work.</div></div></blockquote><di=
v><br>Having a constexpr addressof() is certainly the ideal. But (I think) =
since it cannot be implemented in C++ it makes it a core language extension=
, and requires that the proposal is processed by EWG. Our goal is to make o=
ptional go into C++ library as soon as in 2014 (if this is possible) =
and by adding language extensions we may be unnecessarily making the proces=
s longer. In our proposal, implementations are not forbidden to offer this =
additional feature, and the feature can also be added seamlessly into the f=
uture revisions of C++.<br><br>Regards,<br>&rzej<br></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/?hl=3Den">http://groups.google.com/a/isocpp.org/group/std-pro=
posals/?hl=3Den</a>.<br />
<br />
<br />
------=_Part_1_705647.1361783268509--
.