Topic: std::variant, overload resolution
Author: chris beck <beck.ct@gmail.com>
Date: Tue, 26 Jul 2016 13:51:17 -0400
Raw View
--94eb2c0b75c645b53805388d8c6e
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
Greetings,
This is not actually a proposal, rather, a question about another proposal.
My belief is that this is on-topic -- If this is the wrong place to ask
this question, sorry.
---------------
Variants have become a hot topic in modern C++ in recent years. Beginning
with `boost::variant` and leading into the `std::variant` proposal, variant
has become a part of the modern C++ lexicon.
Much has been written about variants, particularly about the "never-empty"
guarantee, and the costs of this guarantee. For instance, in this article (
https://isocpp.org/blog/2015/11/the-variant-saga-a-happy-ending), the
author states:
> There are other design decisions =E2=80=93 default construction, visitati=
on etc =E2=80=93
but they are all insignificant compared to how to deal with the throwing,
type-changing assignment.
What I would like to ask about is a different issue, which is implicit
conversions.
One thing that was slightly annoying to me about boost::variant was that
things like this would compile:
```
boost::variant<std::string, int> v;
v =3D true
```
and types like `boost::variant<int, float>` could often lead to ambiguous
overload resolution when making assignments to them.
In one project, I wanted to use `boost::variant` to represent a value from
an interface with a scripting language, which naturally would have been
`boost::variant<bool, int, float, std::string, ...>`. But I found it more
complicated than I would like to figure out exactly what the variant was
doing when I made assignments to it. Probably because I'm still a novice
and I generally understand overload resolution from experience rather than
from a close reading of the standard.
What I ended up doing in that project instead was, I made a different
variant type in which overload resolution is not used, and instead it uses
an iterative strategy. I made a type trait that eliminates undesirable
integral conversions, and prevents conversions between integral, floating
point, pointer type, character type, boolean, and wchar_t, and prevents
narrowing conversions. (I won't describe my trait in full detail.)
There are a few drawbacks to a variant like this that I can see.
- With the overload-resolution-based implementation when no match is found,
the compiler will give you list of reasons in each case why the overload
was rejected. When you do iteration via TMP, when you get to the end of the
list the only real error you can give is "no match found". I suppose you
could try to use some really fancy TMP that will accumulate a list of
errors and put that info in the static assert, but I didn't attempt that.
- Overload resolution is a core language feature and everyone already knows
how it works more or less. So even if it doesn't always do what they want,
people will be more comfortable with a variant based on overload resolution
and it will feel more familiar to them.
I guess what I'd like to ask is, since the designers of std::variant
thought that this issue was much less important than the "never empty"
guarantee, can anyone give some insight into how they view this issue? I
used my no-overload resolution version in another project for a while now
and I didn't experience any major usability issues. But maybe there are
more subtle issues I didn't think about, or advantages of the
overload-resolution strategy that I didn't know of.
Would be very interested to hear peoples' opinions.
Best Regards,
Chris Beck
--=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.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/CAF6%2B5c%2B20nmLQzWZGzT9ocfW4fmCyA1Nh9RDoo%2B8g=
yH_Ex3MqQ%40mail.gmail.com.
--94eb2c0b75c645b53805388d8c6e
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div><div><div>Greetings,<br><br></div>This is not actuall=
y a proposal, rather, a question about another proposal. My belief is that =
this is on-topic -- If this is the wrong place to ask this question, sorry.=
<br><br>---------------<br><br></div>Variants have become a hot topic in mo=
dern C++ in recent years. Beginning with `boost::variant` and leading into =
the `std::variant` proposal, variant has become a part of the modern C++ le=
xicon.<br><br></div>Much has been written about variants, particularly abou=
t the "never-empty" guarantee, and the costs of this guarantee. F=
or instance, in this article (<a href=3D"https://isocpp.org/blog/2015/11/th=
e-variant-saga-a-happy-ending">https://isocpp.org/blog/2015/11/the-variant-=
saga-a-happy-ending</a>), the author states:<br><br>> There are other de=
sign decisions =E2=80=93 default construction, visitation etc =E2=80=93
but they are all insignificant compared to how to deal with the=20
throwing, type-changing assignment.<div><div><div><br></div><div>What I wou=
ld like to ask about is a different issue, which is implicit conversions.<b=
r><br></div><div>One thing that was slightly annoying to me about boost::va=
riant was that things like this would compile:<br><br>```<br></div><div>=C2=
=A0=C2=A0=C2=A0 boost::variant<std::string, int> v;<br><br></div><div=
>=C2=A0=C2=A0=C2=A0 v =3D true<br>```<br><br></div><div>and types like `boo=
st::variant<int, float>` could often lead to ambiguous overload resol=
ution when making assignments to them.<br><br></div><div>In one project, I =
wanted to use `boost::variant` to represent a value from an interface with =
a scripting language, which naturally would have been `boost::variant<bo=
ol, int, float, std::string, ...>`. But I found it more complicated than=
I would like to figure out exactly what the variant was doing when I made =
assignments to it. Probably because I'm still a novice and I generally =
understand overload resolution from experience rather than from a close rea=
ding of the standard.<br><br></div><div>What I ended up doing in that proje=
ct instead was, I made a different variant type in which overload resolutio=
n is not used, and instead it uses an iterative strategy. I made a type tra=
it that eliminates undesirable integral conversions, and prevents conversio=
ns between integral, floating point, pointer type, character type, boolean,=
and wchar_t, and prevents narrowing conversions. (I won't describe my =
trait in full detail.)<br><br></div><div>There are a few drawbacks to a var=
iant like this that I can see.<br><br></div><div>- With the overload-resolu=
tion-based implementation when no match is found, the compiler will give yo=
u list of reasons in each case why the overload was rejected. When you do i=
teration via TMP, when you get to the end of the list the only real error y=
ou can give is "no match found". I suppose you could try to use s=
ome really fancy TMP that will accumulate a list of errors and put that inf=
o in the static assert, but I didn't attempt that.<br><br></div><div>- =
Overload resolution is a core language feature and everyone already knows h=
ow it works more or less. So even if it doesn't always do what they wan=
t, people will be more comfortable with a variant based on overload resolut=
ion and it will feel more familiar to them.<br><br></div><div>I guess what =
I'd like to ask is, since the designers of std::variant thought that th=
is issue was much less important than the "never empty" guarantee=
, can anyone give some insight into how they view this issue? I used my no-=
overload resolution version in another project for a while now and I didn&#=
39;t experience any major usability issues. But maybe there are more subtle=
issues I didn't think about, or advantages of the overload-resolution =
strategy that I didn't know of.<br><br>Would be very interested to hear=
peoples' opinions.<br><br></div><div>Best Regards,<br></div><div>Chris=
Beck<br></div></div></div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAF6%2B5c%2B20nmLQzWZGzT9ocfW4fmCyA1N=
h9RDoo%2B8gyH_Ex3MqQ%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfoote=
r">https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAF6%2B5c%2=
B20nmLQzWZGzT9ocfW4fmCyA1Nh9RDoo%2B8gyH_Ex3MqQ%40mail.gmail.com</a>.<br />
--94eb2c0b75c645b53805388d8c6e--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Tue, 26 Jul 2016 13:58:23 -0700 (PDT)
Raw View
------=_Part_672_438808901.1469566703163
Content-Type: multipart/alternative;
boundary="----=_Part_673_1113133103.1469566703164"
------=_Part_673_1113133103.1469566703164
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Tuesday, July 26, 2016 at 1:51:20 PM UTC-4, chris beck wrote:
>
> Greetings,
>
> This is not actually a proposal, rather, a question about another=20
> proposal. My belief is that this is on-topic -- If this is the wrong plac=
e=20
> to ask this question, sorry.
>
> ---------------
>
> Variants have become a hot topic in modern C++ in recent years. Beginning=
=20
> with `boost::variant` and leading into the `std::variant` proposal, varia=
nt=20
> has become a part of the modern C++ lexicon.
>
> Much has been written about variants, particularly about the "never-empty=
"=20
> guarantee, and the costs of this guarantee. For instance, in this article=
(
> https://isocpp.org/blog/2015/11/the-variant-saga-a-happy-ending), the=20
> author states:
>
> > There are other design decisions =E2=80=93 default construction, visita=
tion etc=20
> =E2=80=93 but they are all insignificant compared to how to deal with the=
throwing,=20
> type-changing assignment.
>
> What I would like to ask about is a different issue, which is implicit=20
> conversions.
>
> One thing that was slightly annoying to me about boost::variant was that=
=20
> things like this would compile:
>
> ```
> boost::variant<std::string, int> v;
>
> v =3D true
> ```
>
> and types like `boost::variant<int, float>` could often lead to ambiguous=
=20
> overload resolution when making assignments to them.
>
> In one project, I wanted to use `boost::variant` to represent a value fro=
m=20
> an interface with a scripting language, which naturally would have been=
=20
> `boost::variant<bool, int, float, std::string, ...>`. But I found it more=
=20
> complicated than I would like to figure out exactly what the variant was=
=20
> doing when I made assignments to it. Probably because I'm still a novice=
=20
> and I generally understand overload resolution from experience rather tha=
n=20
> from a close reading of the standard.
>
> What I ended up doing in that project instead was, I made a different=20
> variant type in which overload resolution is not used, and instead it use=
s=20
> an iterative strategy. I made a type trait that eliminates undesirable=20
> integral conversions, and prevents conversions between integral, floating=
=20
> point, pointer type, character type, boolean, and wchar_t, and prevents=
=20
> narrowing conversions. (I won't describe my trait in full detail.)
>
> There are a few drawbacks to a variant like this that I can see.
>
> - With the overload-resolution-based implementation when no match is=20
> found, the compiler will give you list of reasons in each case why the=20
> overload was rejected. When you do iteration via TMP, when you get to the=
=20
> end of the list the only real error you can give is "no match found". I=
=20
> suppose you could try to use some really fancy TMP that will accumulate a=
=20
> list of errors and put that info in the static assert, but I didn't attem=
pt=20
> that.
>
> - Overload resolution is a core language feature and everyone already=20
> knows how it works more or less. So even if it doesn't always do what the=
y=20
> want, people will be more comfortable with a variant based on overload=20
> resolution and it will feel more familiar to them.
>
> I guess what I'd like to ask is, since the designers of std::variant=20
> thought that this issue was much less important than the "never empty"=20
> guarantee, can anyone give some insight into how they view this issue?
>
Well, the alternatives are:
1) Use overload resolution.
2) Use only an exact match.
3) Make up arbitrary rules.
As you point out, #1's rules may be esoteric and unhelpful in some places,=
=20
but they are *consistent*. So you don't have to keep multiple sets of rules=
=20
in mind.
#2 was actually tried in the first proposal: N4218. The constructor from a=
=20
`T&&` was explicit and it only worked if `T` were an exact match for a=20
type. This state of affairs lasted until P0088R1, which the current=20
overload-based form was introduced. However, at no point was it explained=
=20
why this change was adopted.
So in terms of insight, what we can easily determine is that the committee=
=20
preferred #1 over #2. No word on if they considered some from of #3.
Personally, I don't like #3 very much. While I'm against narrowing=20
conversions, I don't think it's worth it to force arbitrary rules on users=
=20
in this way. Even if those rules can be argued to be better than the=20
existing overload rules, it still is inconsistent.
Also, it's something you can fix yourself. It wouldn't be hard at all to=20
write a template function to construct a `std::variant` using your desired=
=20
rules. If you wanted, you could build a whole type around this, with=20
`variant` being used internally to do the hard work.
--=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.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/f9c267dc-77ad-4e9d-a11c-98f3634070a9%40isocpp.or=
g.
------=_Part_673_1113133103.1469566703164
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Tuesday, July 26, 2016 at 1:51:20 PM UTC-4, chris beck =
wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8=
ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><d=
iv><div>Greetings,<br><br></div>This is not actually a proposal, rather, a =
question about another proposal. My belief is that this is on-topic -- If t=
his is the wrong place to ask this question, sorry.<br><br>---------------<=
br><br></div>Variants have become a hot topic in modern C++ in recent years=
.. Beginning with `boost::variant` and leading into the `std::variant` propo=
sal, variant has become a part of the modern C++ lexicon.<br><br></div>Much=
has been written about variants, particularly about the "never-empty&=
quot; guarantee, and the costs of this guarantee. For instance, in this art=
icle (<a href=3D"https://isocpp.org/blog/2015/11/the-variant-saga-a-happy-e=
nding" target=3D"_blank" rel=3D"nofollow" onmousedown=3D"this.href=3D'h=
ttps://www.google.com/url?q\x3dhttps%3A%2F%2Fisocpp.org%2Fblog%2F2015%2F11%=
2Fthe-variant-saga-a-happy-ending\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNH=
ZdBM-aZdgbKKaWtGL8l6u0KIFyg';return true;" onclick=3D"this.href=3D'=
https://www.google.com/url?q\x3dhttps%3A%2F%2Fisocpp.org%2Fblog%2F2015%2F11=
%2Fthe-variant-saga-a-happy-ending\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCN=
HZdBM-aZdgbKKaWtGL8l6u0KIFyg';return true;">https://isocpp.org/blog/201=
5/<wbr>11/the-variant-saga-a-happy-<wbr>ending</a>), the author states:<br>=
<br>> There are other design decisions =E2=80=93 default construction, v=
isitation etc =E2=80=93
but they are all insignificant compared to how to deal with the=20
throwing, type-changing assignment.<div><div><div><br></div><div>What I wou=
ld like to ask about is a different issue, which is implicit conversions.<b=
r><br></div><div>One thing that was slightly annoying to me about boost::va=
riant was that things like this would compile:<br><br>```<br></div><div>=C2=
=A0=C2=A0=C2=A0 boost::variant<std::string, int> v;<br><br></div><div=
>=C2=A0=C2=A0=C2=A0 v =3D true<br>```<br><br></div><div>and types like `boo=
st::variant<int, float>` could often lead to ambiguous overload resol=
ution when making assignments to them.<br><br></div><div>In one project, I =
wanted to use `boost::variant` to represent a value from an interface with =
a scripting language, which naturally would have been `boost::variant<bo=
ol, int, float, std::string, ...>`. But I found it more complicated than=
I would like to figure out exactly what the variant was doing when I made =
assignments to it. Probably because I'm still a novice and I generally =
understand overload resolution from experience rather than from a close rea=
ding of the standard.<br><br></div><div>What I ended up doing in that proje=
ct instead was, I made a different variant type in which overload resolutio=
n is not used, and instead it uses an iterative strategy. I made a type tra=
it that eliminates undesirable integral conversions, and prevents conversio=
ns between integral, floating point, pointer type, character type, boolean,=
and wchar_t, and prevents narrowing conversions. (I won't describe my =
trait in full detail.)<br><br></div><div>There are a few drawbacks to a var=
iant like this that I can see.<br><br></div><div>- With the overload-resolu=
tion-based implementation when no match is found, the compiler will give yo=
u list of reasons in each case why the overload was rejected. When you do i=
teration via TMP, when you get to the end of the list the only real error y=
ou can give is "no match found". I suppose you could try to use s=
ome really fancy TMP that will accumulate a list of errors and put that inf=
o in the static assert, but I didn't attempt that.<br><br></div><div>- =
Overload resolution is a core language feature and everyone already knows h=
ow it works more or less. So even if it doesn't always do what they wan=
t, people will be more comfortable with a variant based on overload resolut=
ion and it will feel more familiar to them.<br><br></div><div>I guess what =
I'd like to ask is, since the designers of std::variant thought that th=
is issue was much less important than the "never empty" guarantee=
, can anyone give some insight into how they view this issue?</div></div></=
div></div></blockquote><div><br>Well, the alternatives are:<br><br>1) Use o=
verload resolution.<br><br>2) Use only an exact match.<br><br>3) Make up ar=
bitrary rules.<br><br>As you point out, #1's rules may be esoteric and =
unhelpful in some places, but they are <i>consistent</i>. So you don't =
have to keep multiple sets of rules in mind.<br><br>#2 was actually tried i=
n the first proposal: N4218. The constructor from a `T&&` was expli=
cit and it only worked if `T` were an exact match for a type. This state of=
affairs lasted until P0088R1, which the current overload-based form was in=
troduced. However, at no point was it explained why this change was adopted=
..<br><br>So in terms of insight, what we can easily determine is that the c=
ommittee preferred #1 over #2. No word on if they considered some from of #=
3.<br><br>Personally, I don't like #3 very much. While I'm against =
narrowing conversions, I don't think it's worth it to force arbitra=
ry rules on users in this way. Even if those rules can be argued to be bett=
er than the existing overload rules, it still is inconsistent.<br><br>Also,=
it's something you can fix yourself. It wouldn't be hard at all to=
write a template function to construct a `std::variant` using your desired=
rules. If you wanted, you could build a whole type around this, with `vari=
ant` being used internally to do the hard work.</div></div>
<p></p>
-- <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 <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/f9c267dc-77ad-4e9d-a11c-98f3634070a9%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/f9c267dc-77ad-4e9d-a11c-98f3634070a9=
%40isocpp.org</a>.<br />
------=_Part_673_1113133103.1469566703164--
------=_Part_672_438808901.1469566703163--
.
Author: chris beck <beck.ct@gmail.com>
Date: Tue, 26 Jul 2016 18:44:58 -0400
Raw View
--94eb2c0b75c6848fb3053891a6ba
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
That's a really good point, thanks.
Chris Beck
On Tue, Jul 26, 2016 at 4:58 PM, Nicol Bolas <jmckesson@gmail.com> wrote:
> On Tuesday, July 26, 2016 at 1:51:20 PM UTC-4, chris beck wrote:
>>
>> Greetings,
>>
>> This is not actually a proposal, rather, a question about another
>> proposal. My belief is that this is on-topic -- If this is the wrong pla=
ce
>> to ask this question, sorry.
>>
>> ---------------
>>
>> Variants have become a hot topic in modern C++ in recent years. Beginnin=
g
>> with `boost::variant` and leading into the `std::variant` proposal, vari=
ant
>> has become a part of the modern C++ lexicon.
>>
>> Much has been written about variants, particularly about the
>> "never-empty" guarantee, and the costs of this guarantee. For instance, =
in
>> this article (
>> https://isocpp.org/blog/2015/11/the-variant-saga-a-happy-ending), the
>> author states:
>>
>> > There are other design decisions =E2=80=93 default construction, visit=
ation etc
>> =E2=80=93 but they are all insignificant compared to how to deal with th=
e throwing,
>> type-changing assignment.
>>
>> What I would like to ask about is a different issue, which is implicit
>> conversions.
>>
>> One thing that was slightly annoying to me about boost::variant was that
>> things like this would compile:
>>
>> ```
>> boost::variant<std::string, int> v;
>>
>> v =3D true
>> ```
>>
>> and types like `boost::variant<int, float>` could often lead to ambiguou=
s
>> overload resolution when making assignments to them.
>>
>> In one project, I wanted to use `boost::variant` to represent a value
>> from an interface with a scripting language, which naturally would have
>> been `boost::variant<bool, int, float, std::string, ...>`. But I found i=
t
>> more complicated than I would like to figure out exactly what the varian=
t
>> was doing when I made assignments to it. Probably because I'm still a
>> novice and I generally understand overload resolution from experience
>> rather than from a close reading of the standard.
>>
>> What I ended up doing in that project instead was, I made a different
>> variant type in which overload resolution is not used, and instead it us=
es
>> an iterative strategy. I made a type trait that eliminates undesirable
>> integral conversions, and prevents conversions between integral, floatin=
g
>> point, pointer type, character type, boolean, and wchar_t, and prevents
>> narrowing conversions. (I won't describe my trait in full detail.)
>>
>> There are a few drawbacks to a variant like this that I can see.
>>
>> - With the overload-resolution-based implementation when no match is
>> found, the compiler will give you list of reasons in each case why the
>> overload was rejected. When you do iteration via TMP, when you get to th=
e
>> end of the list the only real error you can give is "no match found". I
>> suppose you could try to use some really fancy TMP that will accumulate =
a
>> list of errors and put that info in the static assert, but I didn't atte=
mpt
>> that.
>>
>> - Overload resolution is a core language feature and everyone already
>> knows how it works more or less. So even if it doesn't always do what th=
ey
>> want, people will be more comfortable with a variant based on overload
>> resolution and it will feel more familiar to them.
>>
>> I guess what I'd like to ask is, since the designers of std::variant
>> thought that this issue was much less important than the "never empty"
>> guarantee, can anyone give some insight into how they view this issue?
>>
>
> Well, the alternatives are:
>
> 1) Use overload resolution.
>
> 2) Use only an exact match.
>
> 3) Make up arbitrary rules.
>
> As you point out, #1's rules may be esoteric and unhelpful in some places=
,
> but they are *consistent*. So you don't have to keep multiple sets of
> rules in mind.
>
> #2 was actually tried in the first proposal: N4218. The constructor from =
a
> `T&&` was explicit and it only worked if `T` were an exact match for a
> type. This state of affairs lasted until P0088R1, which the current
> overload-based form was introduced. However, at no point was it explained
> why this change was adopted.
>
> So in terms of insight, what we can easily determine is that the committe=
e
> preferred #1 over #2. No word on if they considered some from of #3.
>
> Personally, I don't like #3 very much. While I'm against narrowing
> conversions, I don't think it's worth it to force arbitrary rules on user=
s
> in this way. Even if those rules can be argued to be better than the
> existing overload rules, it still is inconsistent.
>
> Also, it's something you can fix yourself. It wouldn't be hard at all to
> write a template function to construct a `std::variant` using your desire=
d
> rules. If you wanted, you could build a whole type around this, with
> `variant` being used internally to do the hard work.
>
--=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.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/CAF6%2B5c%2BNBVHYYdy-VmTi%2B1PTfGTn-NVf%2BRiNtJM=
-CUmsvQwu8w%40mail.gmail.com.
--94eb2c0b75c6848fb3053891a6ba
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div>That's a really good point, thanks.<br><br></div>=
Chris Beck<br></div><div class=3D"gmail_extra"><br><div class=3D"gmail_quot=
e">On Tue, Jul 26, 2016 at 4:58 PM, Nicol Bolas <span dir=3D"ltr"><<a hr=
ef=3D"mailto:jmckesson@gmail.com" target=3D"_blank">jmckesson@gmail.com</a>=
></span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0=
0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><span=
class=3D"">On Tuesday, July 26, 2016 at 1:51:20 PM UTC-4, chris beck wrote=
:<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;bord=
er-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div><div><div>Gr=
eetings,<br><br></div>This is not actually a proposal, rather, a question a=
bout another proposal. My belief is that this is on-topic -- If this is the=
wrong place to ask this question, sorry.<br><br>---------------<br><br></d=
iv>Variants have become a hot topic in modern C++ in recent years. Beginnin=
g with `boost::variant` and leading into the `std::variant` proposal, varia=
nt has become a part of the modern C++ lexicon.<br><br></div>Much has been =
written about variants, particularly about the "never-empty" guar=
antee, and the costs of this guarantee. For instance, in this article (<a h=
ref=3D"https://isocpp.org/blog/2015/11/the-variant-saga-a-happy-ending" rel=
=3D"nofollow" target=3D"_blank">https://isocpp.org/blog/2015/11/the-variant=
-saga-a-happy-ending</a>), the author states:<br><br>> There are other d=
esign decisions =E2=80=93 default construction, visitation etc =E2=80=93
but they are all insignificant compared to how to deal with the=20
throwing, type-changing assignment.<div><div><div><br></div><div>What I wou=
ld like to ask about is a different issue, which is implicit conversions.<b=
r><br></div><div>One thing that was slightly annoying to me about boost::va=
riant was that things like this would compile:<br><br>```<br></div><div>=C2=
=A0=C2=A0=C2=A0 boost::variant<std::string, int> v;<br><br></div><div=
>=C2=A0=C2=A0=C2=A0 v =3D true<br>```<br><br></div><div>and types like `boo=
st::variant<int, float>` could often lead to ambiguous overload resol=
ution when making assignments to them.<br><br></div><div>In one project, I =
wanted to use `boost::variant` to represent a value from an interface with =
a scripting language, which naturally would have been `boost::variant<bo=
ol, int, float, std::string, ...>`. But I found it more complicated than=
I would like to figure out exactly what the variant was doing when I made =
assignments to it. Probably because I'm still a novice and I generally =
understand overload resolution from experience rather than from a close rea=
ding of the standard.<br><br></div><div>What I ended up doing in that proje=
ct instead was, I made a different variant type in which overload resolutio=
n is not used, and instead it uses an iterative strategy. I made a type tra=
it that eliminates undesirable integral conversions, and prevents conversio=
ns between integral, floating point, pointer type, character type, boolean,=
and wchar_t, and prevents narrowing conversions. (I won't describe my =
trait in full detail.)<br><br></div><div>There are a few drawbacks to a var=
iant like this that I can see.<br><br></div><div>- With the overload-resolu=
tion-based implementation when no match is found, the compiler will give yo=
u list of reasons in each case why the overload was rejected. When you do i=
teration via TMP, when you get to the end of the list the only real error y=
ou can give is "no match found". I suppose you could try to use s=
ome really fancy TMP that will accumulate a list of errors and put that inf=
o in the static assert, but I didn't attempt that.<br><br></div><div>- =
Overload resolution is a core language feature and everyone already knows h=
ow it works more or less. So even if it doesn't always do what they wan=
t, people will be more comfortable with a variant based on overload resolut=
ion and it will feel more familiar to them.<br><br></div><div>I guess what =
I'd like to ask is, since the designers of std::variant thought that th=
is issue was much less important than the "never empty" guarantee=
, can anyone give some insight into how they view this issue?</div></div></=
div></div></blockquote></span><div><br>Well, the alternatives are:<br><br>1=
) Use overload resolution.<br><br>2) Use only an exact match.<br><br>3) Mak=
e up arbitrary rules.<br><br>As you point out, #1's rules may be esoter=
ic and unhelpful in some places, but they are <i>consistent</i>. So you don=
't have to keep multiple sets of rules in mind.<br><br>#2 was actually =
tried in the first proposal: N4218. The constructor from a `T&&` wa=
s explicit and it only worked if `T` were an exact match for a type. This s=
tate of affairs lasted until P0088R1, which the current overload-based form=
was introduced. However, at no point was it explained why this change was =
adopted.<br><br>So in terms of insight, what we can easily determine is tha=
t the committee preferred #1 over #2. No word on if they considered some fr=
om of #3.<br><br>Personally, I don't like #3 very much. While I'm a=
gainst narrowing conversions, I don't think it's worth it to force =
arbitrary rules on users in this way. Even if those rules can be argued to =
be better than the existing overload rules, it still is inconsistent.<br><b=
r>Also, it's something you can fix yourself. It wouldn't be hard at=
all to write a template function to construct a `std::variant` using your =
desired rules. If you wanted, you could build a whole type around this, wit=
h `variant` being used internally to do the hard work.</div></div></blockqu=
ote></div><br></div>
<p></p>
-- <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 <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAF6%2B5c%2BNBVHYYdy-VmTi%2B1PTfGTn-N=
Vf%2BRiNtJM-CUmsvQwu8w%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfoo=
ter">https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAF6%2B5c=
%2BNBVHYYdy-VmTi%2B1PTfGTn-NVf%2BRiNtJM-CUmsvQwu8w%40mail.gmail.com</a>.<br=
/>
--94eb2c0b75c6848fb3053891a6ba--
.
Author: Tony V E <tvaneerd@gmail.com>
Date: Tue, 26 Jul 2016 19:14:20 -0400
Raw View
--001a114b36a49730280538920f8b
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Tue, Jul 26, 2016 at 4:58 PM, Nicol Bolas <jmckesson@gmail.com> wrote:
> On Tuesday, July 26, 2016 at 1:51:20 PM UTC-4, chris beck wrote:
>>
>> Greetings,
>>
>> This is not actually a proposal, rather, a question about another
>> proposal. My belief is that this is on-topic -- If this is the wrong pla=
ce
>> to ask this question, sorry.
>>
>> ---------------
>>
>> Variants have become a hot topic in modern C++ in recent years. Beginnin=
g
>> with `boost::variant` and leading into the `std::variant` proposal, vari=
ant
>> has become a part of the modern C++ lexicon.
>>
>> Much has been written about variants, particularly about the
>> "never-empty" guarantee, and the costs of this guarantee. For instance, =
in
>> this article (
>> https://isocpp.org/blog/2015/11/the-variant-saga-a-happy-ending), the
>> author states:
>>
>> > There are other design decisions =E2=80=93 default construction, visit=
ation etc
>> =E2=80=93 but they are all insignificant compared to how to deal with th=
e throwing,
>> type-changing assignment.
>>
>> What I would like to ask about is a different issue, which is implicit
>> conversions.
>>
>> One thing that was slightly annoying to me about boost::variant was that
>> things like this would compile:
>>
>> ```
>> boost::variant<std::string, int> v;
>>
>> v =3D true
>> ```
>>
>> and types like `boost::variant<int, float>` could often lead to ambiguou=
s
>> overload resolution when making assignments to them.
>>
>>
>>
....
>
> Well, the alternatives are:
>
> 1) Use overload resolution.
>
> 2) Use only an exact match.
>
> 3) Make up arbitrary rules.
>
> As you point out, #1's rules may be esoteric and unhelpful in some places=
,
> but they are *consistent*. So you don't have to keep multiple sets of
> rules in mind.
>
> #2 was actually tried in the first proposal: N4218. The constructor from =
a
> `T&&` was explicit and it only worked if `T` were an exact match for a
> type. This state of affairs lasted until P0088R1, which the current
> overload-based form was introduced. However, at no point was it explained
> why this change was adopted.
>
> So in terms of insight, what we can easily determine is that the committe=
e
> preferred #1 over #2. No word on if they considered some from of #3.
>
I can't recall exactly when this changed in the committee, but I suspect
everyone wanted this to work:
std::variant<std::string, int> vsi =3D "Hello world";
And also, variant<int> should work much like int.
If someone doesn't like some of the conversions (mostly inherited from C),
and I don't blame you if you do, {} construction usually lessens those. So
maybe
std::variant<int> vi =3D 17.2f;
vs
std::variant<int> vi2{17.2f};
I don't actually know which works, I can't find an online compiler with
variant. :-(
--=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.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/CAOHCbisXeHBBqRwTfX-PUHErvQ9DPiiR1F_9T6MPvPrxEiz=
F%2BA%40mail.gmail.com.
--001a114b36a49730280538920f8b
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><div class=3D"gmail_extra"><br><div class=3D"gmail_quo=
te">On Tue, Jul 26, 2016 at 4:58 PM, Nicol Bolas <span dir=3D"ltr"><<a h=
ref=3D"mailto:jmckesson@gmail.com" target=3D"_blank">jmckesson@gmail.com</a=
>></span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 =
0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><spa=
n class=3D"">On Tuesday, July 26, 2016 at 1:51:20 PM UTC-4, chris beck wrot=
e:<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;bor=
der-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div><div><div>G=
reetings,<br><br></div>This is not actually a proposal, rather, a question =
about another proposal. My belief is that this is on-topic -- If this is th=
e wrong place to ask this question, sorry.<br><br>---------------<br><br></=
div>Variants have become a hot topic in modern C++ in recent years. Beginni=
ng with `boost::variant` and leading into the `std::variant` proposal, vari=
ant has become a part of the modern C++ lexicon.<br><br></div>Much has been=
written about variants, particularly about the "never-empty" gua=
rantee, and the costs of this guarantee. For instance, in this article (<a =
href=3D"https://isocpp.org/blog/2015/11/the-variant-saga-a-happy-ending" re=
l=3D"nofollow" target=3D"_blank">https://isocpp.org/blog/2015/11/the-varian=
t-saga-a-happy-ending</a>), the author states:<br><br>> There are other =
design decisions =E2=80=93 default construction, visitation etc =E2=80=93
but they are all insignificant compared to how to deal with the=20
throwing, type-changing assignment.<div><div><div><br></div><div>What I wou=
ld like to ask about is a different issue, which is implicit conversions.<b=
r><br></div><div>One thing that was slightly annoying to me about boost::va=
riant was that things like this would compile:<br><br>```<br></div><div>=C2=
=A0=C2=A0=C2=A0 boost::variant<std::string, int> v;<br><br></div><div=
>=C2=A0=C2=A0=C2=A0 v =3D true<br>```<br><br></div><div>and types like `boo=
st::variant<int, float>` could often lead to ambiguous overload resol=
ution when making assignments to them.<br><br></div><br></div></div></div><=
/blockquote></span></div></blockquote><div><br>...<br>=C2=A0</div><blockquo=
te class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc so=
lid;padding-left:1ex"><div dir=3D"ltr"><span class=3D""></span><div><br>Wel=
l, the alternatives are:<br><br>1) Use overload resolution.<br><br>2) Use o=
nly an exact match.<br><br>3) Make up arbitrary rules.<br><br>As you point =
out, #1's rules may be esoteric and unhelpful in some places, but they =
are <i>consistent</i>. So you don't have to keep multiple sets of rules=
in mind.<br><br>#2 was actually tried in the first proposal: N4218. The co=
nstructor from a `T&&` was explicit and it only worked if `T` were =
an exact match for a type. This state of affairs lasted until P0088R1, whic=
h the current overload-based form was introduced. However, at no point was =
it explained why this change was adopted.<br><br>So in terms of insight, wh=
at we can easily determine is that the committee preferred #1 over #2. No w=
ord on if they considered some from of #3.<br></div></div></blockquote></di=
v><br><br></div><div class=3D"gmail_extra">I can't recall exactly when =
this changed in the committee, but I suspect everyone wanted this to work:<=
br><br></div><div class=3D"gmail_extra">=C2=A0=C2=A0=C2=A0 std::variant<=
std::string, int> vsi =3D "Hello world";<br><br></div><div cla=
ss=3D"gmail_extra">And also, variant<int> should work much like int.<=
br><br></div><div class=3D"gmail_extra">If someone doesn't like some of=
the conversions (mostly inherited from C), and I don't blame you if yo=
u do, {} construction usually lessens those.=C2=A0 So maybe<br><br></div><d=
iv class=3D"gmail_extra">=C2=A0=C2=A0=C2=A0 std::variant<int> vi =3D =
17.2f;<br></div><div class=3D"gmail_extra">vs<br></div><div class=3D"gmail_=
extra">=C2=A0=C2=A0=C2=A0 std::variant<int> vi2{17.2f};<br><br></div>=
<div class=3D"gmail_extra">I don't actually know which works, I can'=
;t find an online compiler with variant. :-(<br></div></div>
<p></p>
-- <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 <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAOHCbisXeHBBqRwTfX-PUHErvQ9DPiiR1F_9=
T6MPvPrxEizF%2BA%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">h=
ttps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAOHCbisXeHBBqR=
wTfX-PUHErvQ9DPiiR1F_9T6MPvPrxEizF%2BA%40mail.gmail.com</a>.<br />
--001a114b36a49730280538920f8b--
.
Author: Edward Catmur <ed@catmur.co.uk>
Date: Tue, 26 Jul 2016 18:20:33 -0700 (PDT)
Raw View
------=_Part_4992_463141665.1469582433962
Content-Type: multipart/alternative;
boundary="----=_Part_4993_897754597.1469582433962"
------=_Part_4993_897754597.1469582433962
Content-Type: text/plain; charset=UTF-8
On Tuesday, 26 July 2016 18:51:20 UTC+1, chris beck wrote:
>
> What I ended up doing in that project instead was, I made a different
> variant type in which overload resolution is not used, and instead it uses
> an iterative strategy. I made a type trait that eliminates undesirable
> integral conversions, and prevents conversions between integral, floating
> point, pointer type, character type, boolean, and wchar_t, and prevents
> narrowing conversions. (I won't describe my trait in full detail.)
>
> There are a few drawbacks to a variant like this that I can see.
>
> - With the overload-resolution-based implementation when no match is
> found, the compiler will give you list of reasons in each case why the
> overload was rejected. When you do iteration via TMP, when you get to the
> end of the list the only real error you can give is "no match found". I
> suppose you could try to use some really fancy TMP that will accumulate a
> list of errors and put that info in the static assert, but I didn't attempt
> that.
>
That sounds like a potential disaster; it's easy to conceive of situations
where the selected type list member would depend on ordering of the type
list i.e. MyVariant<A, B, C>{x} would have a different stored type to
MyVariant<C, B, A>{x}. It would be better to generate a constructor
template for each member of the type list and constrain by your conversion
predicate; this would (with a modern compiler) give sensible errors both
for the no overload and ambiguous overload cases. Admittedly, you'd have to
ensure that exact matches with one of the types were preferred to
conversions to another type, but you could do that with tag dispatch. As
others have said, this would be reinventing overload resolution with
slightly different, unfamiliar and possibly less battle-hardened rules.
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/15ebf8d5-8c47-46a2-b114-fcbddfca6dc5%40isocpp.org.
------=_Part_4993_897754597.1469582433962
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Tuesday, 26 July 2016 18:51:20 UTC+1, chris beck wrote=
:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;bo=
rder-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><div><d=
iv>What I ended up doing in that project instead was, I made a different va=
riant type in which overload resolution is not used, and instead it uses an=
iterative strategy. I made a type trait that eliminates undesirable integr=
al conversions, and prevents conversions between integral, floating point, =
pointer type, character type, boolean, and wchar_t, and prevents narrowing =
conversions. (I won't describe my trait in full detail.)<br></div></div=
></div><div><div><div><br></div><div>There are a few drawbacks to a variant=
like this that I can see.<br><br></div><div>- With the overload-resolution=
-based implementation when no match is found, the compiler will give you li=
st of reasons in each case why the overload was rejected. When you do itera=
tion via TMP, when you get to the end of the list the only real error you c=
an give is "no match found". I suppose you could try to use some =
really fancy TMP that will accumulate a list of errors and put that info in=
the static assert, but I didn't attempt that.=C2=A0<br></div></div></d=
iv></div></blockquote><div><br></div><div>That sounds like a potential disa=
ster; it's easy to conceive of situations where the selected type list =
member would depend on ordering of the type list i.e. MyVariant<A, B, C&=
gt;{x} would have a different stored type to MyVariant<C, B, A>{x}. I=
t would be better to generate a constructor template for each member of the=
type list and constrain by your conversion predicate; this would (with a m=
odern compiler) give sensible errors both for the no overload and ambiguous=
overload cases. Admittedly, you'd have to ensure that exact matches wi=
th one of the types were preferred to conversions to another type, but you =
could do that with tag dispatch. As others have said, this would be reinven=
ting overload resolution with slightly different, unfamiliar and possibly l=
ess battle-hardened rules.</div></div>
<p></p>
-- <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 <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/15ebf8d5-8c47-46a2-b114-fcbddfca6dc5%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/15ebf8d5-8c47-46a2-b114-fcbddfca6dc5=
%40isocpp.org</a>.<br />
------=_Part_4993_897754597.1469582433962--
------=_Part_4992_463141665.1469582433962--
.
Author: Arthur O'Dwyer <arthur.j.odwyer@gmail.com>
Date: Tue, 26 Jul 2016 21:17:20 -0700 (PDT)
Raw View
------=_Part_6753_1472996532.1469593040314
Content-Type: multipart/alternative;
boundary="----=_Part_6754_619497797.1469593040314"
------=_Part_6754_619497797.1469593040314
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Tuesday, July 26, 2016 at 4:14:23 PM UTC-7, Tony V E wrote:
>
> On Tue, Jul 26, 2016 at 4:58 PM, Nicol Bolas <jmck...@gmail.com=20
> <javascript:>> wrote:
>
>>
>> Well, the alternatives are:
>>
>> 1) Use overload resolution.
>> 2) Use only an exact match.
>> 3) Make up arbitrary rules.
>>
>> As you point out, #1's rules may be esoteric and unhelpful in some=20
>> places, but they are *consistent*. So you don't have to keep multiple=20
>> sets of rules in mind.
>>
>> #2 was actually tried in the first proposal: N4218. The constructor from=
=20
>> a `T&&` was explicit and it only worked if `T` were an exact match for a=
=20
>> type. This state of affairs lasted until P0088R1, which the current=20
>> overload-based form was introduced. However, at no point was it explaine=
d=20
>> why this change was adopted.
>>
>> So in terms of insight, what we can easily determine is that the=20
>> committee preferred #1 over #2. No word on if they considered some from =
of=20
>> #3.
>>
>
> I can't recall exactly when this changed in the committee, but I suspect=
=20
> everyone wanted this to work:
>
> std::variant<std::string, int> vsi =3D "Hello world";
>
I was in the room (LEWG) at Kona and I recall that exact example coming up.
In fact I'm pretty sure you were also in the room, Tony. :)
I don't remember whether the debate was between #1 and #2 or between #1 and=
=20
#3; I actually suspect that it was between #1 and #3, in that even the=20
proposal's originators believed that #2 was unworkable.
....In fact, I went and dug up a couple versions of the proposal. N4450 (v2)=
=20
<http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4450.pdf>=20
implements exactly #1, as far as I can tell.
By the time we get to P0088R1 (v6)=20
<http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0088r1.html>, the=
=20
revision history shows that the Kona discussion I remember was actually=20
where LEWG *reversed* its earlier consensus on the undesirability of=20
implicit conversions =E2=80=94
Results of LEWG review in Lenexa:
- Remove conversions, e.g. variant<int, string> x =3D "abc";? SF=3D5 WF=
=3D4=20
N=3D1 WA=3D1 SA=3D0
=20
Results of LEWG review in Kona:
- Allow conversion in both construction and assignment. The detailed=20
polls were:
- keep assignment and construction asymmetrical: SF=3D0, F=3D0, N=3D1, A=
=3D7,=20
SA=3D6
- restrict assign and construction to alternative types only:=20
SF=3D2, F=3D5, N=3D4, A=3D3, SA=3D4
- allow conversion for construction and assignment: SF=3D4, F=3D4,=
=20
N=3D3, A=3D4, SA=3D0
=20
HTH,
=E2=80=93Arthur
--=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.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/39485033-02f3-420c-a1aa-6ad7c11d3eae%40isocpp.or=
g.
------=_Part_6754_619497797.1469593040314
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Tuesday, July 26, 2016 at 4:14:23 PM UTC-7, Tony V E wr=
ote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex=
;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr">On Tue, J=
ul 26, 2016 at 4:58 PM, Nicol Bolas <span dir=3D"ltr"><<a href=3D"javasc=
ript:" target=3D"_blank" gdf-obfuscated-mailto=3D"kauv8MK-BAAJ" rel=3D"nofo=
llow" onmousedown=3D"this.href=3D'javascript:';return true;" onclic=
k=3D"this.href=3D'javascript:';return true;">jmck...@gmail.com</a>&=
gt;</span> wrote:<br><div><div class=3D"gmail_quote"><blockquote class=3D"g=
mail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-l=
eft:1ex"><div dir=3D"ltr"><br></div></blockquote><blockquote class=3D"gmail=
_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:=
1ex"><div dir=3D"ltr"><div>Well, the alternatives are:<br><br>1) Use overlo=
ad resolution.<br>2) Use only an exact match.<br>3) Make up arbitrary rules=
..<br><br>As you point out, #1's rules may be esoteric and unhelpful in =
some places, but they are <i>consistent</i>. So you don't have to keep =
multiple sets of rules in mind.<br><br>#2 was actually tried in the first p=
roposal: N4218. The constructor from a `T&&` was explicit and it on=
ly worked if `T` were an exact match for a type. This state of affairs last=
ed until P0088R1, which the current overload-based form was introduced. How=
ever, at no point was it explained why this change was adopted.<br><br>So i=
n terms of insight, what we can easily determine is that the committee pref=
erred #1 over #2. No word on if they considered some from of #3.<br></div><=
/div></blockquote></div><br></div><div>I can't recall exactly when this=
changed in the committee, but I suspect everyone wanted this to work:<br><=
br></div><div>=C2=A0=C2=A0=C2=A0 std::variant<std::string, int> vsi =
=3D "Hello world";<br></div></div></blockquote><div><br></div><di=
v>I was in the room (LEWG) at Kona and I recall that exact example coming u=
p.</div><div>In fact I'm pretty sure you were also in the room, Tony. :=
)</div><div><br></div><div>I don't remember whether the debate was betw=
een #1 and #2 or between #1 and #3; I actually suspect that it was between =
#1 and #3, in that even the proposal's originators believed that #2 was=
unworkable.</div><div>...In fact, I went and dug up a couple versions of t=
he proposal. <a href=3D"http://www.open-std.org/jtc1/sc22/wg21/docs/papers/=
2015/n4450.pdf">N4450 (v2)</a> implements exactly #1, as far as I can tell.=
</div><div>By the time we get to <a href=3D"http://www.open-std.org/jtc1/sc=
22/wg21/docs/papers/2016/p0088r1.html">P0088R1 (v6)</a>, the revision histo=
ry shows that the Kona discussion I remember was actually where LEWG <i>rev=
ersed</i> its earlier consensus on the undesirability of implicit conversio=
ns =E2=80=94</div><div><br></div><blockquote style=3D"margin: 0 0 0 40px; b=
order: none; padding: 0px;"><div><font size=3D"2" face=3D"arial, sans-serif=
">Results of LEWG review in Lenexa:</font></div></blockquote><ul style=3D"c=
olor: rgb(0, 0, 0);"><ul><li><font size=3D"2" face=3D"arial, sans-serif">Re=
move conversions, e.g.=C2=A0<code>variant<int, string> x =3D "ab=
c";</code>? SF=3D5 WF=3D4 N=3D1 WA=3D1 SA=3D0</font></li></ul></ul><bl=
ockquote style=3D"margin: 0 0 0 40px; border: none; padding: 0px;"><div><fo=
nt size=3D"2" face=3D"arial, sans-serif">=C2=A0Results of LEWG review in Ko=
na:</font></div></blockquote><div><ul style=3D"color: rgb(0, 0, 0);"><ul><l=
i><font size=3D"2" face=3D"arial, sans-serif">Allow conversion in both cons=
truction and assignment. The detailed polls were:</font></li></ul><ul><ul><=
li><font size=3D"2" face=3D"arial, sans-serif">keep assignment and construc=
tion asymmetrical: SF=3D0, F=3D0, N=3D1, A=3D7, SA=3D6</font></li><li><font=
size=3D"2" face=3D"arial, sans-serif">restrict assign and construction to =
alternative types only: SF=3D2, F=3D5, N=3D4, A=3D3, SA=3D4</font></li><li>=
<font size=3D"2" face=3D"arial, sans-serif">allow conversion for constructi=
on and assignment: SF=3D4, F=3D4, N=3D3, A=3D4, SA=3D0</font></li></ul></ul=
></ul><div><font color=3D"#000000" face=3D"arial, sans-serif" size=3D"2">HT=
H,</font></div><div><font color=3D"#000000" face=3D"arial, sans-serif" size=
=3D"2">=E2=80=93Arthur</font></div></div></div>
<p></p>
-- <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 <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/39485033-02f3-420c-a1aa-6ad7c11d3eae%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/39485033-02f3-420c-a1aa-6ad7c11d3eae=
%40isocpp.org</a>.<br />
------=_Part_6754_619497797.1469593040314--
------=_Part_6753_1472996532.1469593040314--
.
Author: chris beck <beck.ct@gmail.com>
Date: Wed, 27 Jul 2016 07:43:44 -0400
Raw View
--94eb2c1246baa0dcc105389c8722
Content-Type: text/plain; charset=UTF-8
> it's easy to conceive of situations where the selected type list member
would depend on ordering of the type list
i guess i was viewing that as a feature, not a bug. The idea was that the
list establishes a priority, so you can put your "smallest" types first and
they will be prioritized in event of a match.
> Admittedly, you'd have to ensure that exact matches with one of the types
were preferred to conversions to another type, but you could do that with
tag dispatch.
That's interesting, i guess I don't see how to do that right now, but I
will think about it.
> As others have said, this would be reinventing overload resolution with
slightly different, unfamiliar and possibly less battle-hardened rules.
Yeah, but at least I don't get implicit conversions. In some use-cases, I
think that's worth it. YMMV I guess.
On Tue, Jul 26, 2016 at 9:20 PM, Edward Catmur <ed@catmur.co.uk> wrote:
> On Tuesday, 26 July 2016 18:51:20 UTC+1, chris beck wrote:
>>
>> What I ended up doing in that project instead was, I made a different
>> variant type in which overload resolution is not used, and instead it uses
>> an iterative strategy. I made a type trait that eliminates undesirable
>> integral conversions, and prevents conversions between integral, floating
>> point, pointer type, character type, boolean, and wchar_t, and prevents
>> narrowing conversions. (I won't describe my trait in full detail.)
>>
>> There are a few drawbacks to a variant like this that I can see.
>>
>> - With the overload-resolution-based implementation when no match is
>> found, the compiler will give you list of reasons in each case why the
>> overload was rejected. When you do iteration via TMP, when you get to the
>> end of the list the only real error you can give is "no match found". I
>> suppose you could try to use some really fancy TMP that will accumulate a
>> list of errors and put that info in the static assert, but I didn't attempt
>> that.
>>
>
> That sounds like a potential disaster; it's easy to conceive of situations
> where the selected type list member would depend on ordering of the type
> list i.e. MyVariant<A, B, C>{x} would have a different stored type to
> MyVariant<C, B, A>{x}. It would be better to generate a constructor
> template for each member of the type list and constrain by your conversion
> predicate; this would (with a modern compiler) give sensible errors both
> for the no overload and ambiguous overload cases. Admittedly, you'd have to
> ensure that exact matches with one of the types were preferred to
> conversions to another type, but you could do that with tag dispatch. As
> others have said, this would be reinventing overload resolution with
> slightly different, unfamiliar and possibly less battle-hardened rules.
>
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAF6%2B5c%2BQXSEtwYkqk%3DU-%3DjcmbE3C5CekMvqKZVbCc_k%3DQAtWpA%40mail.gmail.com.
--94eb2c1246baa0dcc105389c8722
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div><div><div>> it's easy to conceive of situatio=
ns where the selected type list member would depend on ordering of the type=
list<br><br></div>i guess i was viewing that as a feature, not a bug. The =
idea was that the list establishes a priority, so you can put your "sm=
allest" types first and they will be prioritized in event of a match.<=
br><br>> Admittedly, you'd have to ensure that exact matches with on=
e of the=20
types were preferred to conversions to another type, but you could do=20
that with tag dispatch.<br><br></div>That's interesting, i guess I don&=
#39;t see how to do that right now, but I will think about it.<br><br>> =
As others have said, this would be reinventing overload resolution with=20
slightly different, unfamiliar and possibly less battle-hardened rules.<br>=
<br></div>Yeah, but at least I don't get implicit conversions. In some =
use-cases, I think that's worth it. YMMV I guess.<br></div><div class=
=3D"gmail_extra"><br><div class=3D"gmail_quote">On Tue, Jul 26, 2016 at 9:2=
0 PM, Edward Catmur <span dir=3D"ltr"><<a href=3D"mailto:ed@catmur.co.uk=
" target=3D"_blank">ed@catmur.co.uk</a>></span> wrote:<br><blockquote cl=
ass=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;p=
adding-left:1ex"><div dir=3D"ltr"><span class=3D"">On Tuesday, 26 July 2016=
18:51:20 UTC+1, chris beck wrote:<blockquote class=3D"gmail_quote" style=
=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"=
><div dir=3D"ltr"><div><div><div>What I ended up doing in that project inst=
ead was, I made a different variant type in which overload resolution is no=
t used, and instead it uses an iterative strategy. I made a type trait that=
eliminates undesirable integral conversions, and prevents conversions betw=
een integral, floating point, pointer type, character type, boolean, and wc=
har_t, and prevents narrowing conversions. (I won't describe my trait i=
n full detail.)<br></div></div></div><div><div><div><br></div><div>There ar=
e a few drawbacks to a variant like this that I can see.<br><br></div><div>=
- With the overload-resolution-based implementation when no match is found,=
the compiler will give you list of reasons in each case why the overload w=
as rejected. When you do iteration via TMP, when you get to the end of the =
list the only real error you can give is "no match found". I supp=
ose you could try to use some really fancy TMP that will accumulate a list =
of errors and put that info in the static assert, but I didn't attempt =
that.=C2=A0<br></div></div></div></div></blockquote><div><br></div></span><=
div>That sounds like a potential disaster; it's easy to conceive of sit=
uations where the selected type list member would depend on ordering of the=
type list i.e. MyVariant<A, B, C>{x} would have a different stored t=
ype to MyVariant<C, B, A>{x}. It would be better to generate a constr=
uctor template for each member of the type list and constrain by your conve=
rsion predicate; this would (with a modern compiler) give sensible errors b=
oth for the no overload and ambiguous overload cases. Admittedly, you'd=
have to ensure that exact matches with one of the types were preferred to =
conversions to another type, but you could do that with tag dispatch. As ot=
hers have said, this would be reinventing overload resolution with slightly=
different, unfamiliar and possibly less battle-hardened rules.</div></div>=
</blockquote></div><br></div>
<p></p>
-- <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 <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAF6%2B5c%2BQXSEtwYkqk%3DU-%3DjcmbE3C=
5CekMvqKZVbCc_k%3DQAtWpA%40mail.gmail.com?utm_medium=3Demail&utm_source=3Df=
ooter">https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAF6%2B=
5c%2BQXSEtwYkqk%3DU-%3DjcmbE3C5CekMvqKZVbCc_k%3DQAtWpA%40mail.gmail.com</a>=
..<br />
--94eb2c1246baa0dcc105389c8722--
.
Author: Howard Hinnant <howard.hinnant@gmail.com>
Date: Wed, 27 Jul 2016 09:52:57 -0400
Raw View
--Apple-Mail=_421AC312-7534-4A3C-9062-D182965C6C79
Content-Type: text/plain; charset=UTF-8
Fwiw, example implementation of variant as specified in the CD:
https://github.com/efcs/libcxx/blob/variant/include/variant
If you find any difference between the specification and this implementation, speak loudly.
Howard
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/40A16E9E-10BA-4E8B-A8B3-F3E857C80EFE%40gmail.com.
--Apple-Mail=_421AC312-7534-4A3C-9062-D182965C6C79
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
filename=signature.asc
Content-Type: application/pgp-signature;
name=signature.asc
Content-Description: Message signed with OpenPGP using GPGMail
-----BEGIN PGP SIGNATURE-----
iQIcBAEBCAAGBQJXmLy6AAoJEGbcHCxKqhWCNzwP/1roZzyWmMnayt6YtTZz0aqg
9buts9FCHrluCKQ7MyCrR8kZiv4BUoRYJEj/iRvfrYfLLj+iE8zAbjg9nCu29R1v
ExjnDITKZWTOIiux1z3gTQa0C3IlZmDWYEJSHpUEmevIEW5D+YcmBc2ut++wnIX5
ZJNGt+69eA2JE5NyEAlgFjpikJHHJ8hK1AH0jUkY5qoMV1R+GINRTnryq9KWoxng
m66ZcF0okuxDX8ZjiRY1kqpzaI0QbHADrVvwzOatJ7BYcCf8GztgecpaioyLbqQ/
J3lQKdhJYW5YwxZiVCsjXujYMZg+bwV1yaud0bqlZYsOPADZQqjQ85IsQzrrCB8a
AgiM8VXpnH7SOXo0HxnPhcCRX3kK3wPXF07etn1ztVzNNcvimME77YX1TfHOXf3i
TuEsCXHE0Ze41vBWy+zqgxAV7YRGzngagb49LXS7EUSrLzx8VBxFWTUM7uLkUkL5
paN+ON3VbKHojhWc6YtrQJ23QD93MgRXP2sw/ZF8YfKjTt9xs5AZNm3njrypgCv8
Uvk4MuX21/4i/mqj8MMtsjuDeQC9LWGP9KOnJ6oJxEs93NMrQi6ORPJYjlj6e9Eb
noM0LPaRIJb2p7mv3maRva1L1dJkcbJ9S9w45HdNZCrd5Ld94NzFrV330d5SCKKH
JKXvPkOPL9dq9vIkNNkL
=5skt
-----END PGP SIGNATURE-----
--Apple-Mail=_421AC312-7534-4A3C-9062-D182965C6C79--
.