您好,我有一个简单的问题:
class A
{
public:
A(int);
A(const A&);
A& operator=(const A&);
~A();
private:
int* ptr_;
friend bool operator<(const A&, const A&);
friend void swap(A&, A&);
};
A::A(int x) :
ptr_(new int(x))
{}
A::A(const A& rhs) :
ptr_(rhs.ptr_ ? new int(*rhs.ptr_) : nullptr)
{}
A& A::operator = (const A & rhs)
{
int* tmp = rhs.ptr_ ? new int(*rhs.ptr_) : nullptr;
delete ptr_;
ptr_ = tmp;
return *this;
}
A::~A()
{
delete ptr_;
}
bool operator<(const A& lhs, const A& rhs)
{
cout << "operator<(const A&, const A&)" << endl;
return *lhs.ptr_ < *rhs.ptr_;
}
void swap(A& lhs, A& rhs)
{
cout << "swap(A&, A&)" << endl;
using std::swap;
swap(lhs.ptr_, rhs.ptr_);
}
int main()
{
std::vector<A> v{ 33,32,31,30,29,28,27,26,25,24,23,22, 21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5, 4,3,2,1 };
std::sort(v.begin(), v.end());
}
有超过32个元素,排序调用swap
。如果元素少于或等于32个,则这些元素仍会排序,但swap
不会被调用。
- 我在x64上使用MSVC ++ 2019。
- 什么时候
swap
叫,什么时候不叫,为什么?谢谢! swap
在复制分配中,我并没有使用它只是为了区分从复制分配运算符对它的调用。
@Evg是针对此特定上下文的要求还是解释?
—
弗朗索瓦·安德列
@FrançoisAndrieux,这是Microsoft标准库的实现细节。我的猜测是这是OP观察到的行为的原因。我目前正在研究源代码以获取更多详细信息。
—
EVG
来源的相关部分是:
—
ChrisMM
while (_ISORT_MAX < (_Count = _Last - _First) && 0 < _Ideal)
此处_ISORT_MAX
的值为32。<algorithm>
使用VS 16.5.0的第3447 行
在任何语言的任何现代标准库中都没有使用真正的quicksort。所有元素都使用修改后的混合版本,仅当元素数量足够大时才是快速排序。例如,Java和Python使用Timsort,而.NET框架和GCC的C ++库使用Introsort。libstdc ++和libc ++还将插入排序用于短序列。请参阅在不同的STL实现中的C ++ 11 std :: sort使用什么算法?
—
phuclv
std::sort
如果元素数为32以下,则诉诸于插入排序,否则使用快速排序。