Ваш вопрос странный; субъект спрашивает: «Как мне положить вещи в контейнер, не теряя при этом полиморфизма» - но это напрашивается на вопрос; предметы в контейнерах не теряют полиморфизм. У вас просто контейнер базового типа, и все работает.
Из вашего примера видно, что вы спрашиваете: «Как преобразовать контейнер дочерних указателей в контейнер базовых указателей?» - и ответ на этот вопрос, вы не можете. дочерние указатели конвертируются в базовые указатели, контейнеры дочерних указателей - нет. Они не связаны между собой. Хотя, обратите внимание, что shared_ptr можно преобразовать в shared_ptr, но только потому, что у них есть дополнительное волшебство, чтобы заставить это работать. Контейнеры не имеют такой магии.
Одним из ответов было бы сделать chug функцией шаблона (отказ от ответственности: я не на компьютере с компилятором, поэтому я не пытался скомпилировать это):
template<typename C, typename T>
void chug(const C<T>& container)
{
typedef typename C<T>::iterator iter;
for(iter i = container.begin(); i < container.end(); ++i)
{
(*i)->chug();
}
}
Тогда chug может взять любой контейнер любого типа, если он является контейнером указателей и имеет метод chug.