Хотя возможно привести к void *
и обратно, проблема в том, что вы знаете, какой тип вы используете. Ведь вы приводите пример:
Container<string> b = *reinterpret_cast<Container<string>*>(_collection.pop());
Container<int> a = *reinterpret_cast<Container<int>*>(_collection.pop());
Однако, если бы вы случайно сделали:
Container<int> a = *reinterpret_cast<Container<int>*>(_collection.pop());
Container<string> b = *reinterpret_cast<Container<string>*>(_collection.pop());
Теперь у вас есть указатели на неправильный тип, и вы, скорее всего, увидите сбои - или еще хуже.
Если вы хотите сделать что-то подобное, по крайней мере используйте dynamic_cast
, чтобы проверить, что у вас есть нужные типы. С dynamic_cast
вы можете иметь проверку C ++ во время выполнения (используя RTTI ), что ваше приведение является безопасным, если типы приведения (как до, так и после) имеют общий базовый тип с at хотя бы один виртуальный метод.
Итак, сначала создайте общий базовый тип с виртуальным деструктором:
class ContainerBase {
public:
virtual ~ContainerBase() { }
};
Сделайте ваши контейнеры производными от него:
template <typename T>
class Container : public ContainerBase {
// ...
}
Теперь используйте std::stack<ContainerBase *>
. Когда вы получаете предметы из стека, используйте dynamic_cast<Container<int> >(stack.pop())
или dynamic_cast<Container<string> >(stack.pop())
; если у вас неправильные типы, они проверит и вернут NULL.
Тем не менее, гетерогенные контейнеры почти всегда неправильно использовать; на каком-то уровне вам нужно знать, что находится в контейнере, чтобы вы могли использовать его. Чего вы на самом деле пытаетесь достичь, создав такой контейнер?