Puede pasar un puntero de función, objeto de función (o impulsar lambda) a std :: sort para definir un ordenamiento débil estricto de los elementos del contenedor que desea ordenar.Encadenamiento de predicados de ordenamiento (por ejemplo, para std :: sort)
Sin embargo, algunas veces (basta con que haya golpeado esto varias veces), desea poder encadenar comparaciones "primitivas".
Un ejemplo trivial sería si estuviera ordenando una colección de objetos que representan datos de contacto. Algunas veces querrá ordenar por
last name, first name, area code. Otras veces
first name, last name- otras veces
age, first name, area code... etc
Ahora, ciertamente puede escribir un objeto de función adicional para cada caso, pero eso infringe el principio DRY, especialmente si cada comparación es menos trivial.
Parece que debe poder escribir una jerarquía de funciones de comparación: las de bajo nivel hacen las comparaciones simples, primitivas (por ejemplo, nombre del primer nombre <), luego las de nivel superior llaman a las de nivel inferior en sucesión (probablemente encadenando con & & para hacer uso de la evaluación de cortocircuito) para generar las funciones compuestas.
El problema con este enfoque es que std :: sort toma un predicado binario: el predicado solo puede devolver un bool. Entonces, si los estás componiendo no puedes decir si un "falso" indica igualdad o más que. Puede hacer que sus predicados de nivel inferior devuelvan un int, con tres estados, pero luego debería envolverlos en predicados de nivel superior antes de que puedan ser utilizados con std :: sort por sí mismos.
En total, estos no son problemas insuperables. Simplemente parece más difícil de lo que debería ser, y ciertamente invita a una implementación de biblioteca auxiliar.
Por lo tanto, ¿alguien sabe de cualquier biblioteca preexistente (especialmente si se trata de una biblioteca std o boost) que puede ayudar aquí - de tener alguna otra idea al respecto?
[Actualización]
como se menciona en algunos de los comentarios - He ido adelante y escrito mi propia implementación de una clase para manejar esto. Es bastante mínimo, y probablemente tenga algunos problemas con él en general. pero sobre esa base, para cualquier persona interesada, la clase está aquí:
Y algunas funciones auxiliares (para evitar la necesidad de especificar argumentos de plantilla) es aquí:
El problema con esta implementación es que las funciones de comparación de bajo nivel devuelven bools. Solo desea encadenar a la siguiente comparación si la prueba actual compara * igual *. – philsquared
Ver mi propia puñalada en esto que publiqué un enlace en mi respuesta a siukurnin, arriba. Ahora puedo hacer: std :: sort (c.begin(), c.end(), MakeCompareChain (f1, f2, f3)); – philsquared
No, funciona, solo tenemos que hacer dos comparaciones (a == b es lo mismo que no (a