こんにちは私は簡単な質問があります:
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によって観察された動作の理由であると私は推測しています。現在、ソースコードを調べて詳細を調べています。
—
19
ソースの関連部分は次のとおりです。
—
ChrisMM
while (_ISORT_MAX < (_Count = _Last - _First) && 0 < _Ideal)
ここで_ISORT_MAX
、32の値が指定されています<algorithm>
。VS16.5.0 を使用する3447行目
どの言語の最新の標準ライブラリでも、実際のクイックソートは使用されていません。要素の数が十分に多い場合にのみクイックソートである変更された混合バージョンをすべて使用します。JavaやPythonの使用たとえばTimsortは、 .NETフレームワークとGCCのC ++ライブラリを使用していますがイントロソート。libstdc ++およびlibc ++も、短いシーケンスに挿入ソートを使用します。さまざまなSTL実装のC ++ 11 std :: sortで使用されているアルゴリズムを
—
phuclv
std::sort
要素の数が32以下の場合は挿入ソートを使用し、それ以外の場合はクイックソートを使用します。