Boost variant emulates a union but it does not use a union in its implementation. Instead it uses aligned storage and placement new.
It is polymorphic in the sense that if you apply a visitor object on a variant then it will pick the right overload for you. This selection must happen at runtime, but the object code for this is unrolled at compile time. So it's quite fast.