使用自定义的std :: set比较器

我想改变一个整数的项目的默认顺序是字典而不是数字,我不能得到以下用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); ... } 

我得到以下错误:

 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' 

我究竟做错了什么?

你正在使用一个函数,因为你应该使用一个函子(一个重载()运算符的类,所以它可以被称为一个函数)。

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

然后使用类名作为types参数

 set<int64_t, lex_compare> s; 

如果你想避免lex_compare函数样板代码,你也可以使用函数指针(假设lex_compare是一个函数)。

 set<int64_t, bool(*)(const int64_t& lhs, const int64_t& rhs)> s(&lex_compare); 

Yacoby的回答启发我写一个适配器来封装仿函数样板。

 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! 

哇,我认为这是值得的麻烦!

你可以使用一个函数比较器,而不是像这样包装它:

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

每当你需要一组这样的types时,就会感到很烦恼,如果你不用相同的比较器创build所有的组件,就会引起问题。

带有lambda和不带结构或函数的C ++ 11解决scheme:

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

Ideone