Hola tengo una pregunta simple:
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());
}
Con más de 32 elementos, el tipo llama swap
. Con 32 elementos o menos, los elementos todavía están ordenados pero swap
no se llama.
- Estoy usando MSVC ++ 2019 en x64.
- ¿Cuándo se
swap
llama y cuándo no y por qué? ¡Gracias! - No utilicé
swap
en la asignación de copias solo para distinguir entre la llamada y la clasificación del operador de asignación de copias.
@Evg ¿Es eso un requisito o es una explicación para este contexto particular?
—
François Andrieux
@ FrançoisAndrieux, este es un detalle de implementación de la biblioteca estándar de Microsoft. Supongo que esta es la razón del comportamiento observado por OP. Actualmente estoy buscando el código fuente para obtener más detalles.
—
Evg
La parte relevante de la fuente es:
—
ChrisMM
while (_ISORT_MAX < (_Count = _Last - _First) && 0 < _Ideal)
donde _ISORT_MAX
se le da el valor de 32. Línea 3447 de <algorithm>
usar VS 16.5.0
No se utiliza ninguna clasificación rápida real en ninguna biblioteca estándar moderna en ningún idioma. Todos usan versiones mixtas modificadas, que solo es una selección rápida cuando el número de elementos es lo suficientemente grande. Por ejemplo, Java y Python usan Timsort, mientras que .NET Framework y la biblioteca C ++ de GCC usan Introsort . libstdc ++ y libc ++ también usan el tipo de inserción para secuencias cortas. Consulte ¿Qué algoritmos se usan en C ++ 11 std :: sort en diferentes implementaciones de STL?
—
phuclv
std::sort
recurre a la ordenación por inserción si el número de elementos es 32 o menos, y de lo contrario utiliza la ordenación rápida.