Por que std :: sort segfault com comparadores não transitivos?
struct Object
{
int x;
int y;
bool isXValid()
{
return x > 0;
}
};
bool mySort(const Object& lhs, const Object& rhs)
{
// Note the short-circuit here
bool isValidForCheck = lhs.isXValid() && rhs.isXValid();
// rhs may be valid because short-circuit, or both may be invalid
if (isValidForCheck)
{
return lhs.x < rhs.x;
}
return lhs.y < rhs.y;
}
int main()
{
std::vector<Object> myVec;
// random populating of myVec
std::sort(myVec.begin(), myVec.end(), mySort);
return 0;
}
Minha função de comparação é irreflexiva, mas não respeita a transitividade.
ordenação stl - ordenação fraca estrita
Assim, se:
(a < b) == true, (b < a) must be false.
Além disso, se:
a == b, then (a < b) and (b < a) are false.
No entanto, não é transitivo. Por exemplo, com os seguintes valores:
(1, 3) (-1, 2), (3, 1)
Então é possível produzir um contêiner classificado em que:
a < b, and b < c, but c < a.
Esta resposta:O que faz com que std :: sort () acesse o endereço fora do intervalo explica por que std :: sort abordará fora dos limites quando a função de comparação não respeitar a irreflexibilidade (por exemplo, quicksort em que fazemos comp (pivot, pivot) e obtemos true, assim o ponteiro esquerdo continua andando até o final da matriz).
No entanto, estou vendo falhas com comparações irreflexivas, mas não transitivas. Eu também acredito que estou saindo do final da matriz.
Não posso fornecer o código exato aqui, pois é proprietário. O exemplo acima não trava nos meus testes, mas sei que std :: sort selecionará algoritmos diferentes com base no contêiner e nos elementos a serem classificados.
O que eu gostaria de saber é se alguém sabe por que std :: sort falharia no GNU C ++ quando a comparação não é transitiva? Sei que comparações não transitivas quebram o contrato e seu comportamento é indefinido, mas esperava uma resposta semelhante à da pergunta vinculada - ou seja, precisamenteporque pode falhar.