std::vector<std::variant<T>> or std::vector<std::any<T>> then.
What the JVM ends up seeing is something like Java 1.4 bytecode would look like, and there is no need for allocations, because it is only references and generics don't support primitive types.
While C++ templates are monomorphic so a few more tweeks are indeed needed all the way down to machine code.
The principle of cleaning the underlying type applies though.