<div dir="ltr"><div dir="ltr">On Thu, Aug 1, 2019 at 10:57 AM David Greene via llvm-dev <<a href="mailto:llvm-dev@lists.llvm.org">llvm-dev@lists.llvm.org</a>> wrote:<br></div><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><font face="courier new, monospace">  template<typename Tag, typename T><br>
  class StrongTypedef {<br>
  public:<br>
    using BaseType = T;<br>
<br>
  private:<br>
    BaseType Value;<br>
<br>
  public:<br>
    constexpr StrongTypedef() : Value() {}<br>
    constexpr StrongTypedef(const StrongTypedef<Tag, T> &) = default;<br>
    explicit constexpr StrongTypedef(const BaseType &V) : Value(V) {}<br>
    explicit StrongTypedef(BaseType &&V)<br>
        noexcept(std::is_nothrow_move_constructible<BaseType>::value) :<br>
        Value(std::move(V)) {}<br>
<br>
  public:<br>
    explicit operator BaseType&() noexcept {<br>
      return Value;<br>
    }<br>
<br>
    explicit operator const BaseType&() const noexcept {<br>
      return Value;<br>
    }<br>
<br>
    friend void swap(StrongTypedef &A, StrongTypedef &B) noexcept {<br>
      using std::swap;<br>
      swap(static_cast<BaseType&>(A), static_cast<BaseType&>(B));<br>
    }<br>
  };<br></font></blockquote><div><br></div><div>I'm generally a fan of using the type system to encapsulate this kind of thing.  A few points:</div><div><ul><li>Why no move assignment operator?</li><li><font face="courier new, monospace">swap</font> has the wrong <font face="courier new, monospace">noexcept</font> specification.</li><li>In my experience, most of these types end up being equality comparable and hashable.  I understand that equality comparison is separate concern which can be provided by mixins, but the more boilerplate that is required to use it, the less likely people are to adopt it.  This could, of course, be constrained on whether or not the BaseType supports these operations.</li><li>Similar argument about using CRTP, as it requires more boilerplate (the <font face="courier new, monospace">using StrongTypedef::StrongTypedef; </font>statement to bring in the converting constructor).</li><li>Not a fan of the name StrongTypedef (or OpaqueTypedef) either.  If the C++ standard ever acquires related functionality, there will end up being a conceptual mismatch. </li></ul></div></div>-- <br><div dir="ltr" class="gmail_signature"><div dir="ltr"> Nevin ":-)" Liber  <mailto:<a href="mailto:nevin@eviloverlord.com" target="_blank">nevin@cplusplusguy.com</a>>  +1-847-691-1404<br></div></div></div>