title: Correct usage of std::launder
body: <p>I am wanting to confirm that I am correctly using <code>std::launder(...)</code> ensuring that I correctly understand its usage.</p>
  <p>I am creating a <code>Result&lt;U,E&gt;</code> in C++ based off of Rust's implementation.</p>
  <pre class="lang-cpp prettyprint-override"><code>template &lt;typename E&gt;
  class ResultStorage&lt;void, E, std::enable_if_t&lt;std::is_trivially_destructible_v&lt;E&gt;&gt;&gt; {
      using type = typename std::aligned_storage&lt;sizeof(E), alignof(E)&gt;::type;
  
  public:
      explicit constexpr ResultStorage(const Ok&lt;void&gt;&amp;) noexcept : tag_(ResultTag::OK) {}
  
      explicit constexpr ResultStorage(const Ok&lt;void&gt;&amp;&amp;) noexcept : tag_(ResultTag::OK) {}
  
      explicit constexpr ResultStorage(const Err&lt;E&gt;&amp; err) noexcept(std::is_nothrow_copy_constructible&lt;E&gt;())
          : tag_(ResultTag::ERR) {
          new (&amp;error_) E(err.get_error());
      }
      explicit constexpr ResultStorage(const Err&lt;E&gt;&amp;&amp; err) noexcept(std::is_nothrow_move_constructible&lt;E&gt;())
          : tag_(ResultTag::ERR) {
          new (&amp;error_) E(std::move(err.get_error()));
      }
  
      ~ResultStorage() = default;
  
      [[nodiscard]] constexpr E&amp; get_error() &amp; noexcept {
          assert_err(tag_);
          return *std::launder(reinterpret_cast&lt;E*&gt;(&amp;error_));
      }
      
      // Code omitted for brevity
  private:
      ResultTag tag_;
      type error_;
  
      template &lt;typename Rv, typename Ev&gt;
      friend class result::Result;
  };
  </code></pre>
  <p>In the code I use <code>using type = typename std::aligned_storage&lt;sizeof(E), alignof(E)&gt;::type;</code> as my storage type. It is my belief that I need to use <code>std::launder(...)</code> when I return the error type from the function like so:</p>
  <pre class="lang-cpp prettyprint-override"><code>    [[nodiscard]] constexpr E&amp; get_error() &amp; noexcept {
          assert_err(tag_);
          return *std::launder(reinterpret_cast&lt;E*&gt;(&amp;error_));
      }
  </code></pre>
  <p>The reason that I believe I need to use <code>std::launder(...)</code> is because since the incoming error type may be a struct possibly with a <code>const</code> value then it appears that if I do not use <code>std::launder(...)</code> then on first initialization it will refer to the <code>const</code> member value and if I was to reuse this allocated storage it would always refer to the initial <code>const</code> member value.</p>
  <p>I have a rudimentary understanding of <code>std::launder</code> so an explanation of what circumstances require its usage would be appreciated. I have looked at the cppreference for this function but still find it rather mystifying.</p>
  <p>Note: the full impl can be found on <a href="https://github.com/cogle/cogle_utils/blob/master/include/utils/result.hxx#L193" rel="nofollow noreferrer">github</a>.</p>