c++ - 创建需要指向方法函数的指针的模板谓词类,并随之而来的编译器错误

标签 c++ templates function-pointers predicate

我正在构建一系列重复大量代码的谓词,因此将被更改为基于 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 容器执行搜索,并使用我的模板谓词检查 NameElement 相等性像这样:

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/

相关文章:

c++ - 使用什么是正确的类结构?

templates - Chef 模板 - 有条件地插入文本 block

php - Mustache PHP - 如何从数据库加载数据?

c++ - 指向虚函数的指针是否仍会被虚拟调用?

c# - 如何将 C# 函数指针传递给 CLI/C++ 代码?

c++ - 为什么这些模板模棱两可?

c++ - 带有函数签名的 Const 关键字

c++ - alignas() 对 sizeof() 的影响 - 强制性的?

c++ - 推断函数指针或仿函数的返回类型

c++ - 如何将 C 函数指针迁移到 C++?