gpt4 book ai didi

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

转载 作者:搜寻专家 更新时间:2023-10-31 00:47:52 27 4
gpt4 key购买 nike

我正在构建一系列重复大量代码的谓词,因此被更改为基于 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::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/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com