A polymorphic union in C++
I suggest not codifying the derived types suggested in the type. Only note the ultimate base, size and alignment. Thus you are open to later change.
Add a templated alias to get the proper type from base plus candidates.

Assure that no over-sized object is ever assigned in PolyUnionSize, probably best using SFINAE. No need to defer to the user.

Don't assume constructing the new object will never fail.

PolyUnionSize::PolyUnionSize&lt;class D&gt;(D&amp;&amp; d) and PolyUnionSize::operator=&lt;class D&gt;(D&amp;&amp; d) use perfect forwarding. You don't account for that by using std::decay_t where needed, nor heed it when computing noexcept.

The implicit copy-/move- ctor / assignment are only appropriate for trivial types. And in that case, why override the dtor?

As casts should be used sparingly, consider delegating between op* and op-&gt;.