Usando o comparador std :: set personalizado

Eu estou tentando alterar a ordem padrão dos itens em um conjunto de inteiros para ser lexicographic em vez de numérico e não consigo obter o seguinte para compilar 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 s; s.insert(1); ... } 

Estou tendo o erro a seguir:

 error: type/value mismatch at argument 2 in template parameter list for 'template class std::set' error: expected a type, got 'lex_compare' 

O que estou fazendo de errado?

Você está usando uma function onde você deve usar um functor (uma class que sobrecarrega o operador () para que ele possa ser chamado como uma function).

 struct lex_compare { bool operator() (const int64_t& lhs, const int64_t& rhs) const { stringstream s1, s2; s1 < < lhs; s2 << rhs; return s1.str() < s2.str(); } }; 

Você então usa o nome da class como o parâmetro de tipo

 set s; 

Se você quiser evitar o código boilerplate functor, você também pode usar um ponteiro de function (assumindo que lex_compare é uma function).

 set s(&lex_compare); 

A resposta de Yacoby me inspira a escrever um adaptador para encapsular o boilerplate functor.

 template< class T, bool (*comp)( T const &, T const & ) > class set_funcomp { struct ftor { bool operator()( T const &l, T const &r ) { return comp( l, r ); } }; public: typedef std::set< T, ftor > t; }; // usage bool my_comparison( foo const &l, foo const &r ); set_funcomp< foo, my_comparison >::t boo; // just the way you want it! 

Uau, acho que valeu a pena!

Solução C ++ 11 com lambda e sem estrutura ou function:

 auto cmp = [](int a, int b) { return ... }; set s(cmp); 

Ideone

Você pode usar um comparador de funções sem envolvê-lo assim:

 bool comparator(const MyType &lhs, const MyType &rhs) { return [...]; } std::set mySet(&comparator); 

que é irritante digitar sempre que você precisar de um conjunto desse tipo, e pode causar problemas se você não criar todos os conjuntos com o mesmo comparador.