Topic: Allow `explicit` function arguments to prevent


Author: Jonathan Coe <jonathanbcoe@gmail.com>
Date: Wed, 3 May 2017 14:07:44 +0100
Raw View
--001a1148d008f87e3f054e9e59df
Content-Type: text/plain; charset=UTF-8

I've run into a use case recently where generating a hash for a variant
type caused run-time issues due to infinite recursion.

Using overload from
http://open-std.org/JTC1/SC22/WG21/docs/papers/2016/p0051r2.pdf
and hash_append from
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3980.html I wrote
code similar to the following:

```
using my_variant_t = std::variant<A,B,C>;

template <class H>
void hash_append(H& h, const my_variant_t& v)
{
  using std::hash_append;
  auto o = std::overload([&h](const auto& x) { hash_append(h, x); });
  std::visit(o, v);
}
```

If hash_append is not specialized for A,B or C then this results in
infinite recursion as my_variant_t can be implicitly constructed from A,B,
or C.

I can prevent the infinite recursion, and require specialization of
hash_append for all variant sub-types, by additionally defining:

```
template <class H>
void hash_append(H& h, my_variant_t&& v) = delete;
```

I'd rather write

```
template <class H>
void hash_append(H& h, explicit const my_variant_t& v) // note use of
`explicit` keyword
{
  using std::hash_append;
  auto o = std::overload([&h](const auto& x) { hash_append(h, x); });
  std::visit(o, v);
}
```

to prevent implicit conversions and do the same thing.

What do other people think?

regards,

Jon

--
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/CAAbBDD9BRHFXOKG2MZdQs%2Bn9hP7R_s81EQQ-fa0D22yynh_TYQ%40mail.gmail.com.

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

<div dir=3D"ltr">I&#39;ve run into a use case recently where generating a h=
ash for a variant type caused run-time issues due to infinite recursion.<di=
v><br></div><div>Using overload from=C2=A0<a href=3D"http://open-std.org/JT=
C1/SC22/WG21/docs/papers/2016/p0051r2.pdf">http://open-std.org/JTC1/SC22/WG=
21/docs/papers/2016/p0051r2.pdf</a>=C2=A0</div><div>and hash_append from <a=
 href=3D"http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3980.html=
">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3980.html</a>=C2=
=A0I wrote code similar to the following:</div><div><br></div><div>```</div=
><div>using my_variant_t =3D std::variant&lt;A,B,C&gt;;</div><div><br></div=
><div>template &lt;class H&gt;</div><div>void hash_append(H&amp; h, const m=
y_variant_t&amp; v)</div><div>{</div><div>=C2=A0 using std::hash_append;</d=
iv><div>=C2=A0 auto o =3D std::overload([&amp;h](const auto&amp; x) { hash_=
append(h, x); });</div><div>=C2=A0 std::visit(o, v);</div><div>}</div><div>=
```</div><div><br></div><div>If hash_append is not specialized for A,B or C=
 then this results in infinite recursion as my_variant_t can be implicitly =
constructed from A,B, or C.</div><div><br></div><div>I can prevent the infi=
nite recursion, and require specialization of hash_append for all variant s=
ub-types, by additionally defining:</div><div><br></div><div>```</div><div>=
<div>template &lt;class H&gt;</div><div>void hash_append(H&amp; h, my_varia=
nt_t&amp;&amp; v) =3D delete;</div></div><div>```</div><div><br></div><div>=
I&#39;d rather write=C2=A0</div><div><br></div><div>```</div><div><div>temp=
late &lt;class H&gt;</div><div>void hash_append(H&amp; h, explicit const my=
_variant_t&amp; v) // note use of `explicit` keyword</div><div>{</div><div>=
=C2=A0 using std::hash_append;</div><div>=C2=A0 auto o =3D std::overload([&=
amp;h](const auto&amp; x) { hash_append(h, x); });</div><div>=C2=A0 std::vi=
sit(o, v);</div><div>}</div></div><div>```</div><div><br></div><div>to prev=
ent implicit conversions and do the same thing.</div><div><br></div><div>Wh=
at do other people think?</div><div><br></div><div>regards,</div><div><br><=
/div><div>Jon</div><div><br></div><div><br></div><div><br></div></div>

<p></p>

-- <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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAAbBDD9BRHFXOKG2MZdQs%2Bn9hP7R_s81EQ=
Q-fa0D22yynh_TYQ%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">h=
ttps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAAbBDD9BRHFXOK=
G2MZdQs%2Bn9hP7R_s81EQQ-fa0D22yynh_TYQ%40mail.gmail.com</a>.<br />

--001a1148d008f87e3f054e9e59df--

.