Topic: N4542: Should we be able to "widen


Author: Patrice Roy <patricer@gmail.com>
Date: Thu, 29 Oct 2015 19:43:56 -0400
Raw View
--047d7bdc0dd264f5f0052346e209
Content-Type: text/plain; charset=UTF-8

Wouldn't there be semantic difficulties when there are two occurrences of
the same type in a given variant? The variant that was voted is ordered, as
variant<T,U> != variant<U,T>, and accepts variant<T,U,T> which will let it
fit well with existing discriminated unions, but I don't know to which T a
given variant<T,U> ou variant<U,T> should map in such a case.

I'd prefer it, given the accepted design, if we relied on user
transformations in narrowing cases (even though I find the idea
interesting).

2015-10-29 19:10 GMT-04:00 Nicol Bolas <jmckesson@gmail.com>:

> On Thursday, October 29, 2015 at 6:09:38 PM UTC-4, Arthur O'Dwyer wrote:
>>
>> This question came up at the Mountain View meetup last night.
>>
>> I can imagine wanting to do this:
>>
>>     using Value = std::variant<int,double,std::string,List,Object>;
>>     using Simple = std::variant<int,double,std::string>;
>>     using Numeric = std::variant<int,double>;
>>
>>     void func(Simple x);
>>
>>     Numeric n;
>>     func(n);  // Should this work, somehow, since every Numeric "is-a"
>> Simple in some sense?
>>
>
> Could it work? Yes. Should it work? Not implicitly; if it should be
> allowed, there ought to be a function for it. When should it work? Well,
> that's the question.
>
>
>>
>>     Value v;
>>     func(v);  // Should this compile, somehow, and then throw at runtime
>> if v holds a List or Object?
>>
>
> No, it should not. Not implicitly.
>
> The "narrowing" case is sort of like dynamic_cast;
>>
>
> In no sense is it like a dynamic cast. `dynamic_cast` is about casting
> within a class hierarchy. Specifically, from child to parent. The only way
> it's similar is that it can conceptually fail.
>
> Or, is there a clever trick to get this kind of behavior already, without
>> having to write an arcane and expensive helper function that does a bunch
>> of get()s and assignments?
>>
>
> There is nothing arcane about a simple visitor:
>
> template<typename ...Args>
> variant_conv
> {
>   template<typename T>
>   variant<Args...> operator()(const T &t) const
>   {
>     //If T not in Args, throw.
>     return t;
>   }
> };
>
> auto v = visit(variant_conv<int, float, std::string>{}, variant<int, float
> >{3.4f});
>
> You can even wrap that up in a template function.
>
> --
>
> ---
> You received this message because you are subscribed to the Google Groups
> "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> Visit this group at
> http://groups.google.com/a/isocpp.org/group/std-proposals/.
>

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

--047d7bdc0dd264f5f0052346e209
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div>Wouldn&#39;t there be semantic difficulties when ther=
e are two occurrences of the same type in a given variant? The variant that=
 was voted is ordered, as variant&lt;T,U&gt; !=3D variant&lt;U,T&gt;, and a=
ccepts variant&lt;T,U,T&gt; which will let it fit well with existing discri=
minated unions, but I don&#39;t know to which T a given variant&lt;T,U&gt; =
ou variant&lt;U,T&gt; should map in such a case.<br><br></div>I&#39;d prefe=
r it, given the accepted design, if we relied on user transformations in na=
rrowing cases (even though I find the idea interesting).<br></div><div clas=
s=3D"gmail_extra"><br><div class=3D"gmail_quote">2015-10-29 19:10 GMT-04:00=
 Nicol Bolas <span dir=3D"ltr">&lt;<a href=3D"mailto:jmckesson@gmail.com" t=
arget=3D"_blank">jmckesson@gmail.com</a>&gt;</span>:<br><blockquote class=
=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padd=
ing-left:1ex"><div dir=3D"ltr"><span class=3D"">On Thursday, October 29, 20=
15 at 6:09:38 PM UTC-4, Arthur O&#39;Dwyer wrote:<blockquote class=3D"gmail=
_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padd=
ing-left:1ex"><div dir=3D"ltr">This question came up at the Mountain View m=
eetup last night.<div><br></div><div>I can imagine wanting to do this:</div=
><div><br></div><div>=C2=A0 =C2=A0 using Value =3D std::variant&lt;int,doub=
le,std::string,List,Object&gt;;</div><div>=C2=A0 =C2=A0 using Simple =3D st=
d::variant&lt;int,double,std::string&gt;;</div><div>=C2=A0 =C2=A0 using Num=
eric =3D std::variant&lt;int,double&gt;;</div><div><br></div><div>=C2=A0 =
=C2=A0 void func(Simple x);</div><div><br></div><div>=C2=A0 =C2=A0 Numeric =
n;</div><div>=C2=A0 =C2=A0 func(n); =C2=A0// Should this work, somehow, sin=
ce every Numeric &quot;is-a&quot; Simple in some sense?</div></div></blockq=
uote></span><div><br>Could it work? Yes. Should it work? Not implicitly; if=
 it should be allowed, there ought to be a function for it. When should it =
work? Well, that&#39;s the question.<br>=C2=A0</div><span class=3D""><block=
quote 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><br></div><div>=C2=
=A0 =C2=A0 Value v;</div><div>=C2=A0 =C2=A0 func(v); =C2=A0// Should this c=
ompile, somehow, and then throw at runtime if v holds a List or Object?</di=
v></div></blockquote></span><div><br>No, it should not. Not implicitly.<br>=
<br></div><span class=3D""><blockquote class=3D"gmail_quote" style=3D"margi=
n:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=
=3D"ltr"><div></div><div>The &quot;narrowing&quot; case is sort of like dyn=
amic_cast;</div></div></blockquote></span><div><br>In no sense is it like a=
 dynamic cast. `dynamic_cast` is about casting within a class hierarchy. Sp=
ecifically, from child to parent. The only way it&#39;s similar is that it =
can conceptually fail. <br><br></div><span class=3D""><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>Or, is there a clever t=
rick to get this kind of behavior already, without having to write an arcan=
e and expensive helper function that does a bunch of get()s and assignments=
?</div></div></blockquote></span><div><br>There is nothing arcane about a s=
imple visitor:<br><br><div style=3D"background-color:rgb(250,250,250);borde=
r-color:rgb(187,187,187);border-style:solid;border-width:1px;word-wrap:brea=
k-word"><code><div><span style=3D"color:#008">template</span><span style=3D=
"color:#660">&lt;</span><span style=3D"color:#008">typename</span><span sty=
le=3D"color:#000"> </span><span style=3D"color:#660">...</span><span style=
=3D"color:#606">Args</span><span style=3D"color:#660">&gt;</span><span styl=
e=3D"color:#000"><br>variant_conv<br></span><span style=3D"color:#660">{</s=
pan><span style=3D"color:#000"><br>=C2=A0 </span><span style=3D"color:#008"=
>template</span><span style=3D"color:#660">&lt;</span><span style=3D"color:=
#008">typename</span><span style=3D"color:#000"> T</span><span style=3D"col=
or:#660">&gt;</span><span style=3D"color:#000"><br>=C2=A0 variant</span><sp=
an style=3D"color:#660">&lt;</span><span style=3D"color:#606">Args</span><s=
pan style=3D"color:#660">...&gt;</span><span style=3D"color:#000"> </span><=
span style=3D"color:#008">operator</span><span style=3D"color:#660">()(</sp=
an><span style=3D"color:#008">const</span><span style=3D"color:#000"> T </s=
pan><span style=3D"color:#660">&amp;</span><span style=3D"color:#000">t</sp=
an><span style=3D"color:#660">)</span><span style=3D"color:#000"> </span><s=
pan style=3D"color:#008">const</span><span style=3D"color:#000"><br>=C2=A0 =
</span><span style=3D"color:#660">{</span><span style=3D"color:#000"><br>=
=C2=A0 =C2=A0 </span><span style=3D"color:#800">//If T not in Args, throw.<=
/span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"co=
lor:#008">return</span><span style=3D"color:#000"> t</span><span style=3D"c=
olor:#660">;</span><span style=3D"color:#000"><br>=C2=A0 </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 st=
yle=3D"color:#008">auto</span><span style=3D"color:#000"> v </span><span st=
yle=3D"color:#660">=3D</span><span style=3D"color:#000"> visit</span><span =
style=3D"color:#660">(</span><span style=3D"color:#000">variant_conv</span>=
<span style=3D"color:#660">&lt;</span><span style=3D"color:#008">int</span>=
<span style=3D"color:#660">,</span><span style=3D"color:#000"> </span><span=
 style=3D"color:#008">float</span><span style=3D"color:#660">,</span><span =
style=3D"color:#000"> std</span><span style=3D"color:#660">::</span><span s=
tyle=3D"color:#008">string</span><span style=3D"color:#660">&gt;{},</span><=
span style=3D"color:#000"> variant</span><span style=3D"color:#660">&lt;</s=
pan><span style=3D"color:#008">int</span><span style=3D"color:#660">,</span=
><span style=3D"color:#000"> </span><span style=3D"color:#008">float</span>=
<span style=3D"color:#660">&gt;{</span><span style=3D"color:#066">3.4f</spa=
n><span style=3D"color:#660">});</span></div></code></div><br>You can even =
wrap that up in a template function.<br></div></div><div class=3D"HOEnZb"><=
div class=3D"h5">

<p></p>

-- <br>
<br>
--- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org" target=3D"_=
blank">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" target=3D"_blank">http://groups.google.com/a/isocpp.org/gro=
up/std-proposals/</a>.<br>
</div></div></blockquote></div><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&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--047d7bdc0dd264f5f0052346e209--

.