Estou tentando alterar a ordem padrão dos itens em um conjunto de inteiros para serem lexicográficos em vez de numéricos e não consigo compilar o seguinte com 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);
...
}
Estou tendo o erro a seguir:
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’
O que estou fazendo de errado?
std::set<int64_t, decltype(&lex_compare)> s(&lex_compare)
1. Solução C ++ 20 moderna
Usamos a função lambda como comparador. Como de costume, o comparador deve retornar um valor booleano, indicando se o elemento passado como primeiro argumento é considerado anterior ao segundo na ordem estrita e fraca específica que define.
Demo online
2. Solução C ++ 11 moderna
Antes do C ++ 20, precisamos passar lambda como argumento para definir o construtor
Demo online
3. Semelhante à primeira solução, mas com função em vez de lambda
Faça comparador como função booleana usual
Em seguida, use-o desta forma:
Demo online
ou assim:
Demo online
4. Solução antiga usando struct com
()
operadorDemo online
5. Solução alternativa: crie uma estrutura a partir da função booleana
Pegue a função booleana
E faça uma estrutura a partir dele usando
std::integral_constant
Finalmente, use a estrutura como comparador
Demo online
fonte
A resposta de Yacoby me inspira a escrever um adaptador para encapsular o boilerplate do functor.
Nossa, acho que valeu a pena!
fonte
Você pode usar um comparador de função sem agrupá-lo da seguinte maneira:
o que é irritante de digitar toda vez que você precisa de um conjunto desse tipo e pode causar problemas se você não criar todos os conjuntos com o mesmo comparador.
fonte
std::less<>
ao usar classes personalizadas comoperator<
Se você está lidando com um conjunto de sua classe personalizada que foi
operator<
definida, então você pode apenas usarstd::less<>
.Conforme mencionado em http://en.cppreference.com/w/cpp/container/set/find, C ++ 14 adicionou duas novas
find
APIs:que permitem que você faça:
main.cpp
Compile e execute:
Mais informações sobre
std::less<>
podem ser encontradas em: O que são comparadores transparentes?Testado no Ubuntu 16.10,
g++
6.2.0.fonte