不提供这些重载有很好的“设计理念”原因。特别是,整个 STL 容器/算法交互旨在通过不同的迭代器概念,使这两个部分保持独立,这样您就可以定义新的容器类型而不必为所有算法重载,这样您就可以定义新算法,而不必为所有容器重载。
除了这些设计选择之外,还有一个很好的技术原因,为什么这些算法(排序、下限等)不能为特殊容器(如list
or map
/ )重载set
。原因是迭代器通常没有理由显式连接到它们的父容器。换句话说,您可以从列表容器中获取列表迭代器(开始/结束),但不能从列表迭代器中获取(引用)列表容器。map / set 迭代器也是如此。迭代器可以被实现为对其父容器“盲目”。例如,像这样的容器list
通常包含指向头和尾节点的指针以及分配器对象作为数据成员,但迭代器本身(通常只是指向节点的指针)不需要知道头/尾或分配器,它们只是有走上一个/下一个链接指针在列表中来回移动。因此,如果您要实现std::sort
for 的重载list
容器,将无法从传递给排序函数的迭代器中检索列表容器。而且,在您提到的所有情况下,适用于这些特殊容器的算法版本是“集中的”,因为它们需要在容器级别运行,而不是在“盲”迭代器级别运行。这就是为什么它们作为成员函数有意义,这就是为什么你不能从迭代器中得到它们。
但是,如果您需要一种通用的方式来调用这些算法而不管您拥有的容器是什么,那么您可以根据需要在容器级别提供重载的函数模板。就这么简单:
template <typename Container>
void sort_container(Container& c) {
std::sort(begin(c), end(c));
};
template <typename T, typename Alloc>
void sort_container(std::list<T, Alloc>& c) {
c.sort();
};
template <typename Key, typename T, typename Compare, typename Alloc>
void sort_container(std::map<Key, T, Compare, Alloc>&) { /* nothing */ };
//... so on..
这里的重点是,如果你已经绑定了 STL 容器,那么如果你愿意的话,你可以通过这种方式绑定 STL 算法……但不要指望 C++ 标准库会强迫你拥有这种容器和算法之间的相互依赖,因为不是每个人都想要它们(例如,很多人非常喜欢 STL 算法,但不喜欢 STL 容器(有很多问题))。