Topic: N4542: Should we be able to "widen" variant<A,B> to


Author: Arthur O'Dwyer <arthur.j.odwyer@gmail.com>
Date: Thu, 29 Oct 2015 15:09:38 -0700 (PDT)
Raw View
------=_Part_70_1170242611.1446156578164
Content-Type: multipart/alternative;
 boundary="----=_Part_71_1282629741.1446156578164"

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

This question came up at the Mountain View meetup last night.

I can imagine wanting to do this:

    using Value =3D std::variant<int,double,std::string,List,Object>;
    using Simple =3D std::variant<int,double,std::string>;
    using Numeric =3D std::variant<int,double>;

    void func(Simple x);

    Numeric n;
    func(n);  // Should this work, somehow, since every Numeric "is-a"=20
Simple in some sense?

    Value v;
    func(v);  // Should this compile, somehow, and then throw at runtime if=
=20
v holds a List or Object?

The "narrowing" case is sort of like dynamic_cast; I could picture it being=
=20
done via

    func(dynamic_variant_cast<Simple>(v));

The "widening" case is more like

    func(static_variant_cast<Simple>(n));

The obvious problem to be surmounted here is to formalize what it means for=
=20
Numeric to "be-a-subset-of" Simple.
Should I be able to convert variant<int,double> to=20
variant<string,int,double>?
What about to variant<int,double,int>?

Another related idea that was floated was that there should be a variadic=
=20
form of std::get<>, something like:

    std::tuple<A,B,C> tup =3D ...;
    std::tuple<C,B> x =3D std::tuple_get<3,2>(tup);

and similarly

    std::variant<A,B,C> tup =3D ...;
    std::variant<C,B> x =3D std::variant_get<3,2>(tup);  // or throw if "tu=
p"=20
doesn't hold B or C


Or, is there a clever trick to get this kind of behavior already, without=
=20
having to write an arcane and expensive helper function that does a bunch=
=20
of get()s and assignments?

Or, are the obvious problems enough to kill this idea entirely (like, it's=
=20
not something you should be trying to do in the first place)?

=E2=80=93Arthur

--=20

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

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

<div dir=3D"ltr">This question came up at the Mountain View meetup last nig=
ht.<div><br></div><div>I can imagine wanting to do this:</div><div><br></di=
v><div>=C2=A0 =C2=A0 using Value =3D std::variant&lt;int,double,std::string=
,List,Object&gt;;</div><div>=C2=A0 =C2=A0 using Simple =3D std::variant&lt;=
int,double,std::string&gt;;</div><div>=C2=A0 =C2=A0 using Numeric =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, since every Numeric=
 &quot;is-a&quot; Simple in some sense?</div><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 runtime if v holds a List or Object?</div><div>=
<br></div><div>The &quot;narrowing&quot; case is sort of like dynamic_cast;=
 I could picture it being done via</div><div><br></div><div>=C2=A0 =C2=A0 f=
unc(dynamic_variant_cast&lt;Simple&gt;(v));</div><div><br></div><div>The &q=
uot;widening&quot; case is more like</div><div><br></div><div><div>=C2=A0 =
=C2=A0 func(static_variant_cast&lt;Simple&gt;(n));</div></div><div><br></di=
v><div>The obvious problem to be surmounted here is to formalize what it me=
ans for Numeric to &quot;be-a-subset-of&quot; Simple.</div><div>Should I be=
 able to convert variant&lt;int,double&gt; to variant&lt;string,int,double&=
gt;?</div><div>What about to variant&lt;int,double,int&gt;?</div><div><br><=
/div><div>Another related idea that was floated was that there should be a =
variadic form of std::get&lt;&gt;, something like:</div><div><br></div><div=
>=C2=A0 =C2=A0 std::tuple&lt;A,B,C&gt; tup =3D ...;</div><div>=C2=A0 =C2=A0=
 std::tuple&lt;C,B&gt; x =3D std::tuple_get&lt;3,2&gt;(tup);</div><div><div=
><br></div></div><div>and similarly</div><div><br></div><div><div>=C2=A0 =
=C2=A0 std::variant&lt;A,B,C&gt; tup =3D ...;</div><div>=C2=A0 =C2=A0 std::=
variant&lt;C,B&gt; x =3D std::variant_get&lt;3,2&gt;(tup); =C2=A0// or thro=
w if &quot;tup&quot; doesn&#39;t hold B or C</div><div></div></div><div><br=
></div><div><br></div><div>Or, is there a clever trick to get this kind of =
behavior already, without having to write an arcane and expensive helper fu=
nction that does a bunch of get()s and assignments?</div><div><br></div><di=
v>Or, are the obvious problems enough to kill this idea entirely (like, it&=
#39;s not something you should be trying to do in the first place)?</div><d=
iv><br></div><div>=E2=80=93Arthur</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&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_71_1282629741.1446156578164--
------=_Part_70_1170242611.1446156578164--

.