Generally I find it's best to implement push operations as try_push operations and let the caller decide if they want to drop, or spin.
There are definitely designs that can deal with non-POD data of variable size, although that does imply heterogeneous types, which will need some sort of type erasure to destroy safely.