Estoy tratando de cambiar el orden predeterminado de los elementos en un conjunto de enteros para que sean lexicográficos en lugar de numéricos, y no puedo compilar lo siguiente con g ++:
file.cpp:
bool lex_compare(const int64_t &a, const int64_t &b)
{
stringstream s1,s2;
s1 << a;
s2 << b;
return s1.str() < s2.str();
}
void foo()
{
set<int64_t, lex_compare> s;
s.insert(1);
...
}
Obtuve el siguiente error:
error: type/value mismatch at argument 2 in template parameter list for ‘template<class _Key, class _Compare, class _Alloc> class std::set’
error: expected a type, got ‘lex_compare’
¿Qué estoy haciendo mal?
std::set<int64_t, decltype(&lex_compare)> s(&lex_compare)
1. Solución C ++ 20 moderna
Usamos la función lambda como comparador. Como de costumbre, el comparador debe devolver un valor booleano, indicando si el elemento pasado como primer argumento se considera que va antes que el segundo en el orden débil estricto específico que define.
Demostración online
2. Solución moderna de C ++ 11
Antes de C ++ 20 necesitamos pasar lambda como argumento para establecer el constructor
Demostración online
3. Similar a la primera solución, pero con función en lugar de lambda
Hacer comparador como función booleana habitual
Luego úsalo, ya sea de esta manera:
Demostración online
o de esta manera:
Demostración online
4. Solución anterior que usa estructura con
()
operadorDemostración online
5. Solución alternativa: cree una estructura a partir de una función booleana
Toma la función booleana
Y haz una estructura a partir de él usando
std::integral_constant
Finalmente, use la estructura como comparador
Demostración online
fuente
La respuesta de Yacoby me inspira a escribir un adaptador para encapsular el functor boilerplate.
¡Vaya, creo que valió la pena!
fuente
Puede usar un comparador de funciones sin envolverlo así:
lo cual es irritante escribir cada vez que necesita un conjunto de ese tipo y puede causar problemas si no crea todos los conjuntos con el mismo comparador.
fuente
std::less<>
al usar clases personalizadas conoperator<
Si está tratando con un conjunto de su clase personalizada que se ha
operator<
definido, entonces puede usarstd::less<>
.Como se menciona en http://en.cppreference.com/w/cpp/container/set/find C ++ 14 ha agregado dos nuevas
find
API:que te permiten hacer:
main.cpp
Compilar y ejecutar:
std::less<>
Puede encontrar más información sobre : ¿Qué son los comparadores transparentes?Probado en Ubuntu 16.10,
g++
6.2.0.fuente