Я пытаюсь изменить порядок по умолчанию пунктов в ряде целых чисел, чтобы быть лексикографическим вместо числового, и я не могу заставить следующее компилировать с 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();
}
};
Затем вы используете имя класса в качестве параметра типа
set<int64_t, lex_compare> s;
Если вы хотите избежать использования шаблонного кода функтора, вы также можете использовать указатель на функцию (при условии, что lex_compare
является функцией).
set<int64_t, bool(*)(const int64_t& lhs, const int64_t& rhs)> s(&lex_compare);
Ответ Якоби вдохновляет меня написать адаптер для инкапсуляции шаблона функтора.
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!
Ого, я думаю, это того стоило!