Създавам поредица от предикати, които дублират много код и така се променят в единичен шаблонен функционален клас, базиран на 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, което съм пропуснал, което върши същата работа в един клас? Винаги мога да разделя предиката на няколко по-конкретни, но се опитвам да избегна това.
Второ, можете ли да ми помогнете с грешките на компилатора?