Я создаю серию предикатов, которые дублируют много кода, и поэтому они превращаются в один класс функции шаблона на основе std::unary_function
. Идея состоит в том, что интерфейс моего класса требует, чтобы были определены такие методы, как Element_t Element()
и std::string Name()
, поэтому аргументами шаблона предиката являются тип объекта и тип значения, с которыми будет производиться сравнение следующим образом:
// generic predicate for comparing an attribute of object pointers to a specified test value
template <class U, typename R>
class mem_fun_eq : public std::unary_function <U*, bool> {
private:
typedef R (U::*fn_t)();
fn_t fn;
R val;
public:
explicit mem_fun_eq (fn_t f, R& r) : fn(f), val(r) { }
bool operator() (U * u) const {
return (u->*fn)() == val;
}
};
Таким образом, если у меня есть:
class Atom {
public:
const Element_t& Element() const { return _element; }
const std::string& Name() const { return _name; }
};
Я хотел бы выполнить поиск в контейнере Atom
s и проверить равенство Name
или Element
, используя мой предикат шаблона следующим образом:
typedef std::string (Atom::*fn)() const;
Atom_it it = std::find_if( _atoms.begin(), _atoms.end(), mem_fun_eq <Atom, std::string> ((fn)&Atom::Name, atomname));
но при его компиляции в строке std::find_if
возвращается следующая ошибка:
error: address of overloaded function with no contextual type information
Также, пытаясь сформировать тот же предикат для проверки Element()
как такового:
typedef Atom::Element_t& (Atom::*fn)() const;
Atom_it it = std::find_if(_atoms.begin(), _atoms.end(), mem_fun_eq <Atom, Atom::Element_t> ((fn)&Atom::Element, elmt);
создает другую ошибку!
error: no matching function for call to ‘mem_fun_eq<Atom, Atom::Element_t>::mem_fun_eq(Atom::Element_t& (Atom::*)()const, const Atom::Element_t&)’
note: candidates are: mem_fun_eq<U, R>::mem_fun_eq(R (U::*)(), R&) [with U = Atom, R = Atom::Element_t]
note: mem_fun_eq<Atom, Atom::Element_t>::mem_fun_eq(const mem_fun_eq<Atom, Atom::Element_t>&)
Во-первых, изобретаю ли я велосипед с помощью этого предиката? Есть ли в STL что-то, что я пропустил, что делает ту же работу в одном классе? Я всегда могу разбить предикат на несколько более конкретных, но я стараюсь этого избежать.
Во-вторых, можете ли вы мне помочь с ошибками компилятора?