为何 C++ 不提供多态的(heterogeneous)容器

C++ 标准库提供了一套非常好用的、静态类型安全的、高效的容器。例如 vector、list,以及 map:

所有优秀的 C++ 教材都有对这些容器的描述。应该优先使用标准容器,而非数组和“自制的”容器,除非你有很充分的不使用 STL 的理由。
这些容器都是单态的;亦即,它们的元素是同一类型的。如果你希望某个容器能保存多种类型的元素,必须使用联合体或者在容器里保存指向多态类型的指针(这个方法通常更好)。一个经典的例子是:
vector<Shape*> vi; // 该 vector 保存指向 Shape 的指针
在此,vi 的元素可以是从 Shape 派生出来的任何类型(的指针)。亦即,既可以说 vi 是单态的,因为其所有元素都是 Shape(精确地说是指向 Shape 的指针),也可以说它是多态的,因为它可以保存多种类型的 Shape,例如 Circles、Triangles 等等。
所以,可以说,所有容器(无论任何语言)都是单态的,因为为了使用它们,必须有一个可供用户用来访问其中所有元素的公共接口。提供多态容器的语言,其实无 非是容器里的元素都提供了一个标准的接口。例如,Java collection 提供的容器保存的是 Object 类型(的引用),可用(公共的)Object 接口来获取元素的真正类型。

C++ 标准库提供单态的容器,因为大多数情况下,它们常用且易用,并能提供尽可能好的编译时错误信息,而且没有不必要的运行时开销。

如果你需要在 C++ 中使用多态的容器,可为所有元素定义一个公共的接口,然后即可制出这样的容器。例如:
class Io_obj { /* … */ }; // 进行 I/O 所需的接口

vector<Io_obj*> vio;??? // 如果你想直接管理指针
vector< Handle<Io_obj> > v2; // 如果你想用“智能指针”来处理各个对象
如非必要,绝对不要使用最底层的实现细节:
vector<void*> memory; // 很少用到
辨别你是否“走入底层”的一个很好的办法是,看看你的代码里是否夹杂着显式类型转换。
在某些程序里,也可以使用 Any 类(例如 Boost::Any):

vector<Any> v;