Topic: N4542: Should we be able to "widen" variant<A,B>
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Thu, 29 Oct 2015 16:10:23 -0700 (PDT)
Raw View
------=_Part_14_1132156555.1446160224012
Content-Type: multipart/alternative;
boundary="----=_Part_15_2090865752.1446160224012"
------=_Part_15_2090865752.1446160224012
Content-Type: text/plain; charset=UTF-8
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/.
------=_Part_15_2090865752.1446160224012
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Thursday, October 29, 2015 at 6:09:38 PM UTC-4, Arthur =
O'Dwyer wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;marg=
in-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"=
ltr">This question came up at the Mountain View meetup 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<int,double,std::<wbr>string,List=
,Object>;</div><div>=C2=A0 =C2=A0 using Simple =3D std::variant<int,d=
ouble,std::<wbr>string>;</div><div>=C2=A0 =C2=A0 using Numeric =3D std::=
variant<int,double>;</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, since every Numeric=
"is-a" Simple in some sense?</div></div></blockquote><div><br>Co=
uld 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.<br>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"mar=
gin: 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 compile, somehow, and then throw at r=
untime if v holds a List or Object?</div></div></blockquote><div><br>No, it=
should not. Not implicitly.<br><br></div><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>The "narrowing" case=
is sort of like dynamic_cast;</div></div></blockquote><div><br>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 simila=
r is that it can conceptually fail. <br><br></div><blockquote class=3D"gmai=
l_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 =
trick to get this kind of behavior already, without having to write an arca=
ne and expensive helper function that does a bunch of get()s and assignment=
s?</div></div></blockquote><div><br>There is nothing arcane about a simple =
visitor:<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">template</span><span style=3D"color: #660;" class=3D"styled-by-prettify=
"><</span><span style=3D"color: #008;" class=3D"styled-by-prettify">type=
name</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">...</span><span=
style=3D"color: #606;" class=3D"styled-by-prettify">Args</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">></span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"><br>variant_conv<br></span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"><br>=C2=A0 </span><span style=3D"=
color: #008;" class=3D"styled-by-prettify">template</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify"><</span><span style=3D"color: #=
008;" class=3D"styled-by-prettify">typename</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> T</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">></span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"><br>=C2=A0 variant</span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify"><</span><span style=3D"color: #606;" class=3D=
"styled-by-prettify">Args</span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">...></span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-prettif=
y">operator</span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>()(</span><span style=3D"color: #008;" class=3D"styled-by-prettify">const<=
/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">t</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">)</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" clas=
s=3D"styled-by-prettify">const</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"><br>=C2=A0 </span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">{</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #800;" class=3D"=
styled-by-prettify">//If T not in Args, throw.</span><span style=3D"color: =
#000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D=
"color: #008;" class=3D"styled-by-prettify">return</span><span style=3D"col=
or: #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>=C2=A0 </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></span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">};</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"><br><br></span><span style=3D"color: #008;" class=3D"styled-by-prettify">=
auto</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> v </s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> visit</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify">variant_conv</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify"><</span><span style=3D"color=
: #008;" class=3D"styled-by-prettify">int</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: #008;" class=3D"style=
d-by-prettify">float</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> std</span><span style=3D"color: #660;" class=3D"styled-by-prettify">::</s=
pan><span style=3D"color: #008;" class=3D"styled-by-prettify">string</span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">>{},</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> variant</span><span=
style=3D"color: #660;" class=3D"styled-by-prettify"><</span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">int</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">float</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">>{</span><span style=3D"color: #066;" class=3D"styled=
-by-prettify">3.4f</span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">});</span></div></code></div><br>You can even wrap that up in a tem=
plate function.<br></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 <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_15_2090865752.1446160224012--
------=_Part_14_1132156555.1446160224012--
.
Author: Larry Evans <cppljevans@suddenlink.net>
Date: Sat, 31 Oct 2015 15:23:40 -0500
Raw View
On 10/29/2015 05:09 PM, 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?
>
> Value v;
> func(v); // Should this compile, somehow, and then throw at runtime
> if v holds a List or Object?
>
IIUC, then wouldn't variant<> be narrower than any other
variant; hence:
variant<> narrowest;
func(narrowest);
should work?
-regards,
Larry
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Larry Evans <cppljevans@suddenlink.net>
Date: Sun, 1 Nov 2015 01:18:33 -0600
Raw View
On 10/31/2015 03:23 PM, Larry Evans wrote:
> On 10/29/2015 05:09 PM, 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?
>>
>> Value v;
>> func(v); // Should this compile, somehow, and then throw at runtime
>> if v holds a List or Object?
>>
>
> IIUC, then wouldn't variant<> be narrower than any other
> variant; hence:
>
> variant<> narrowest;
> func(narrowest);
>
> should work?
>
And just as:
variant<T0,T1> is *narrower* than variant<T0,T1,T2>
then by duality in category theory:
https://en.wikipedia.org/wiki/Opposite_category
the following would be the dual definition of narrower:
tuple<T0,T1,T2> is *narrower* than tuple<T0,T1>
hence, any function taking a tuple<T0,T1> should also take a
tuple<T0,T1,T2> and tuple<> would be the *widest* tuple.
BTW, if "is narrower" is replaced with "is subtype", then
this seems to be consistent with:
https://en.wikipedia.org/wiki/Structural_type_system
which claims:
One type is a subtype of another if and only if it
contains all the features of the base type (or subtypes
thereof); the subtype may contain additional features
(such as members not present in the base type, or stronger
invariants).
because:
tuple<T0,T1,T2> contains all the features (i.e. get<I> for
i=0,1) of the base type, tuple<T0,T1>)
-regards,
Larry
--
---
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/.
.