为什么C++标准模板库不包含矢量的"sort"成员函数?
Why doesn't the C++ Standard Template Library include a "sort" member function for vectors?
我注意到C++标准模板库包含用于列表对象的排序成员函数,但由于某些原因,它不包含用于向量的此成员函数。
这看起来很草率,前后矛盾。。。
下面是一个示例:
#include <iostream>
#include <algorithm>
#include <vector>
#include <list>
using namespace std;
// Template function to print the contents of a container
template <typename Container>
void PrintContainer(const Container& container)
{
cout << "{ ";
Container::const_iterator i;
for (i = container.begin(); i != container.end(); i++)
{
cout << *i << ' ';
}
cout << "}" << endl;
}
// Main
int main()
{
vector<int> v;
list<int> l;
// Initialize the vector and the list in descending order
for (int i = 10; i > 0; i--)
{
v.push_back(i);
l.push_back(i);
}
// Print the contents
cout << "Vector = ";
PrintContainer(v);
cout << "List = ";
PrintContainer(l);
cout << endl;
// Sort the vector and the list...
cout << "Sorting..." << endl << endl;
// Doesn't work... no member function exists, but why??
// v.sort();
// I have to do this annoying garbage instead...
sort(v.begin(), v.end());
// Works fine
l.sort();
// Print the contents
cout << "Vector = ";
PrintContainer(v);
cout << "List = ";
PrintContainer(l);
cout << endl;
return 0;
}
我在某个地方读到,排序和其他成员函数被添加到列表模板中,以确保指针在执行不同的操作后仍然有效,但这并不能解释为什么他们会选择不为向量实现这一点。
为什么他们会选择为列表而不是向量实现这一点
实现不仅简单,而且会使标准模板类更加一致。。。在开发一个将被数百万程序员学习并广泛使用的接口时,一致性非常重要!
实现不仅简单,而且会使标准模板类更加一致。。。
不,不会。
在提出更一致的主张之前,请阅读STL的设计和理念。它可能更符合您的期望,或者与您使用过的其他类库一致,但它与STL设计的其余部分不一致。
Stepanov的天才,也是泛型编程的原则之一,在于提升通用抽象,将算法与容器分离,这样std::sort()
函数就可以有效地用于任何随机访问容器,而不需要在每个容器上一次又一次地重新实现。
STL的规则是,只有当操作执行通用非成员版本无法执行的时,才将其定义为成员函数。因此,list::sort()
允许对不可交换对象的列表进行排序,而std::sort()
不能对列表进行排序(因为它没有随机访问迭代器),并且要求元素是可交换的。list::sort()
也是稳定的,并保持迭代器的有效性,参见STL文档中关于list
:的注释6
排序算法仅适用于随机访问迭代器。然而,原则上,可以编写一个也接受双向迭代器的排序算法。即使有这样一个版本的排序,列表中有一个排序成员函数仍然很有用。也就是说,提供排序作为成员函数不仅是为了提高效率,还因为它保留了列表迭代器指向的值
有关仅当容器的行为与通用算法不同时才在容器上定义成员函数的原则的进一步讨论,请参见有效STL项44。
实际上真正的问题是"当有一个非常好的std::sort
算法时,为什么std::list
有一个sort
成员?"。(注意:std::sort
是对vector
和大多数其他容器进行排序的方式)
当你以这种方式看待这个问题时,很明显list
是规则的例外,它实现了自己的成员排序函数,因为对于列表来说,它可以更有效地实现。
这与std::find
和std::map::find
完全类似,其中map
提供其自己的查找功能,该查找功能工作效率高得多。
std::sort和std::stable_sort可以处理数组、向量等对象,以及任何具有随机访问迭代器的对象。std::sort通常是quicksort/heapsort的混合,称为introsort。std::stable_sort通常是某种类型的合并排序。std::list:sort设计用于处理单链表。对于双链表,内部先前的节点指针由后排序处理
std::list::sort算法经过优化,可用于链表。示例代码与HP/Microsoft版本的std::list::sort中使用的代码类似。使用指向内部列表的第一个节点的指针数组,其中array[i]为NULL或指向具有pow(2,i)节点的列表(除了最后一个指针列表大小不受限制)。实际的排序是使用标准的合并列表函数完成的。节点一次取一个并合并到数组中,然后将数组合并到单个列表中。这与用于std::sort或std::stable_sort的算法有很大不同。
NODE * MergeLists(NODE *pSrc1, NODE *pSrc2)
{
NODE *pDst = NULL; /* destination head ptr */
NODE **ppDst = &pDst; /* ptr to head or prev->next */
if(pSrc1 == NULL)
return pSrc2;
if(pSrc2 == NULL)
return pSrc1;
while(1){
if(pSrc2->data < pSrc1->data){ /* if src2 < src1 */
*ppDst = pSrc2;
pSrc2 = *(ppDst = &(pSrc2->next));
if(pSrc2 == NULL){
*ppDst = pSrc1;
break;
}
} else { /* src1 <= src2 */
*ppDst = pSrc1;
pSrc1 = *(ppDst = &(pSrc1->next));
if(pSrc1 == NULL){
*ppDst = pSrc2;
break;
}
}
}
return pDst;
}
#define NUMLISTS 32 /* size of aList[] */
NODE * SortList(NODE *pList)
{
NODE * aList[NUMLISTS]; /* array of lists */
NODE * pNode;
NODE * pNext;
int i;
if(pList == NULL) /* check for empty list */
return NULL;
for(i = 0; i < NUMLISTS; i++) /* zero array */
aList[i] = NULL;
pNode = pList; /* merge nodes into aList[] */
while(pNode != NULL){
pNext = pNode->next;
pNode->next = NULL;
for(i = 0; (i < NUMLISTS) && (aList[i] != NULL); i++){
pNode = MergeLists(aList[i], pNode);
aList[i] = NULL;
}
if(i == NUMLISTS)
i--;
aList[i] = pNode;
pNode = pNext;
}
pNode = NULL; /* merge array into one list */
for(i = 0; i < NUMLISTS; i++)
pNode = MergeLists(aList[i], pNode);
return pNode;
}
- 将成员变量添加到共享库中的类中,不会破坏二进制兼容性吗
- 对RValue对象调用的LValue ref限定成员函数
- 为什么使用 "this" 指针调用派生成员函数?
- 具有奇怪重复模板模式的派生类中的成员变量已损坏
- 助记符和指向成员语法的指针
- 用于访问容器<T>数据成员的正确 API
- 内置函数可查看CPP中的成员变量
- 是否可以初始化不可复制类型的成员变量(或基类)
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- 为什么 std::sort 找不到合适的(静态成员)函数重载?
- 请求成员 'begin' in 'c' 中,它是非类类型 'char [101]' sort(c.begin(), c
- 使用 vector.sort() 的非静态成员函数无效使用
- 错误:"类 std::vector<Shape*>"没有名为"sort"的成员
- 将“std::sort”与模板化类中的成员函数一起使用
- 为什么C++标准模板库不包含矢量的"sort"成员函数?
- 测试容器是否实现.at()成员访问/ std::sort兼容的正确方法
- c++ std::sort():仅使用一个比较函数的任何可比较成员的对象向量
- 错误:'sort'不是 'std' 的成员
- 使用sort()排序成员向量的比较函数
- 命名空间"std"没有成员"sort"