我正在构建一系列重复大量代码的谓词,因此将被更改为基于 std::unary_function
的单个模板函数类。我的想法是,我的类接口(interface)需要定义 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
容器执行搜索,并使用我的模板谓词检查 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 中是否有我错过的东西可以在单个类中完成相同的工作?我总是可以将谓词分解为几个更具体的谓词,但我试图避免这种情况。
其次,你能帮我解决编译器错误吗?
最佳答案
我不知道有什么简单的方法可以使用 STL 提供的位来完成此操作。可能有一些聪明的 boost 方法,使用迭代器适配器或 boost::lambda,但我个人不会这样做。
显然,C++0x lambda 将使这一切变得简单。
您的问题是尝试转换这样的函数:
const std::string&(Atom::*)()
像这样的函数:
std::string (Atom::*)()
如果将 typedef R (U::*fn_t)();
替换为 typedef const R& (U::*fn_t)() const;
那么它应该可以。
下面的代码避免了这个问题,并且还提供了类型推断,这样你就可以编写mem_fun_eq(&Atom::Name,atomname)
。它可以为我编译,尽管我还没有测试过。
template<typename U, typename R, typename S>
class mem_fun_eq_t : public std::unary_function<U const*, bool>
{
private:
R (U::*fn_)() const;
S val_;
public:
mem_fun_eq_t(R (U::*fn )() const, S val) : fn_(fn), val_(val){}
bool operator()(U * u)
{
return (u->*fn_)() == val_;
}
};
template<typename U, typename R, typename S>
mem_fun_eq_t<U, R, S> mem_fun_eq(R (U::*fn)() const, S val)
{
return mem_fun_eq_t<U, R, S>(fn, val);
}
关于c++ - 创建需要指向方法函数的指针的模板谓词类,并随之而来的编译器错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3339286/