Usando il comparatore personalizzato std :: set

Sto cercando di modificare l’ordine predefinito degli elementi in un insieme di numeri interi in modo lessicografico anziché numerico e non riesco a ottenere quanto segue per compilare 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 s; s.insert(1); ... } 

Ottengo il seguente errore:

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

Che cosa sto facendo di sbagliato?

Stai utilizzando una funzione in cui dovresti usare un functor (una class che sovraccarica l’operatore () in modo che possa essere chiamata come una funzione).

 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(); } }; 

Quindi si utilizza il nome della class come parametro del tipo

 set s; 

Se vuoi evitare il codice functor boilerplate puoi anche usare un puntatore a funzione (assumendo che lex_compare sia una funzione).

 set s(&lex_compare); 

La risposta di Yacoby mi ispira a scrivere un adattatore per incapsulare la piastra del funtore.

 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! 

Wow, penso che ne valeva la pena!

Soluzione C ++ 11 con lambda e senza struttura o funzione:

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

Ideone

Puoi usare un comparatore di funzioni senza avvolgerlo in questo modo:

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

che è irritante da digitare ogni volta che è necessario un set di quel tipo e può causare problemi se non si creano tutti i set con lo stesso comparatore.