#include <algorithm>
#include <iostream>
#include <list>
#include <vector>
class Int
{
public:
Int(int i = 0) : m_i(i) { }
public:
bool operator<(const Int& a) const { return this->m_i < a.m_i; }
Int& operator=(const Int &a)
{
this->m_i = a.m_i;
++m_assignments;
return *this;
}
static int get_assignments() { return m_assignments; }
private:
int m_i;
static int m_assignments;
};
int Int::m_assignments = 0;
int main()
{
std::list<Int> l({ Int(3), Int(1) });
l.sort();
std::cout << (Int::get_assignments() > 0 ? 1 : 0);
std::vector<Int> v({ Int(2), Int() });
std::sort(v.begin(), v.end());
std::cout << (Int::get_assignments() > 0 ? 2 : 0) << std::endl;
return 0;
}
以上代码打印出02
,这意味着std::list::sort()
在operator=()
std::sort()
列表的元素上不执行任何分配操作(std::vector
)确实对Int
的元素执行至少1次赋值操作。
差异源于什么?容器类?实现排序? {{1}}类实现?
答案 0 :(得分:3)
std::list
是一个双向链表,这意味着只需修改列表中的指针即可对其进行排序。不需要元素分配。
一个简单的例子就是:
head --> 2 --> 1 --> null
可以按以下方式排序:
______________ | | | v head -' 2 <-- 1 +-> null | | '-------------'
不复制任何元素。
事实上,根据C++11 23.3.5.5 list operations /29
,保持迭代器和引用有效的要求意味着,为了提高效率,它实际上无法移动
效果:根据
operator<
或Compare
函数对象对列表进行排序。 不影响迭代器和引用的有效性。
std::vector
将其项保持在一个连续的数组中,因此没有指针可以操作。如果您想要对其进行排序,则必须移动项目。