Это возможно с Boost.Variant (фиксированное число различных типов) или Boost.Any (тип, который может хранить любой тип, в основном ваш «указатель пустоты», но с информацией о типе).
Также возможно, если String и Integer были получены из полиморфного базового класса. (Но для этого им придется реализовать один и тот же интерфейс, что может или не может быть возможным в вашем случае.)
Как правило, полиморфизм - это самый простой способ сделать это, и он действительно используется постоянно.
Вариант и Любой требует много работы: вам все равно нужно каким-то образом получить содержимое как нужный тип, который они хранят. (Вроде как если бы вы использовали приведения к производным классам вместо того, чтобы полагаться на полиморфные вызовы методов.)