将函数作为参数传递给方法c ++

时间:2015-02-08 15:38:19

标签: c++ overloading

在搜索论坛寻找答案后,我似乎无法解决此问题。

出于教学目的,我正在创建一个(模板)链表类。我的班级有以下方法:

template <typename E>
bool List<E>::hasValue(E value, bool (*fn)(E, E)){
    bool hasValue = false;
    node* c = head;
    while (true) {
        if (c->value == value) {
            hasValue = true;
            break;
        }
        else if (c->next != 0) {
            c = c->next;
        }
        else {
            break;
        }
    }
    return hasValue;
}

我希望bool (*fn)(E, E)成为用户定义的任何重载运算符==,如下所示:

struct record {
    string name;
    int age;
};

bool operator==(const record& r1, const record& r2) {
    bool result = false;
    if (r1.name == r2.name && r1.age == r2.age) {
        result = true;
    }
    return result;
}

但是如果我打电话给list.hasValue({"duder", 20}, operator==) Xcode报告:

  

没有匹配的成员函数来调用'hasValue'

我似乎无法在网上找到解释原因的原因。

2 个答案:

答案 0 :(得分:1)

你不想要像

这样的东西
 if ((*fn)(c->value,value)) {...}

另外,我建议将参数作为const引用传递。

另外,由于这是一个模板函数,你确定你在声明它的同一个头文件中定义了这个函数吗?

答案 1 :(得分:1)

您可以使用通用比较器概念:

template <typename E, typename Comp>
bool List<E>::hasValue(E value, Comp fn) { ... }

这使您可以避免指定函数签名(这实际上不会让您获得任何东西)。

然后你可以把它称为:

list.hasValue(record{"duder", 20}, std::equal_to<record>());

std::equal_to导入<functional>。这个仿函数will call operator==如果存在的话。


实际上,我还建议,出于语义目的,如果未明确定义比较器,则自动默认使用std::equal_to定义中的hasValue

template <typename E, typename Comp = std::equal_to<E>>
bool List<E>::hasValue(E value, Comp fn = {}) { ... }