2015-02-08 141 views
1

在搜索论坛寻找答案后,我似乎无法解决此问题。将函数作为参数传递给方法C++

为了教学目的,我创建了一个(模板)链表类。我班有以下方法:

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'

我似乎无法找到任何这种情况发生的原因的在线解释。

+0

你'==操作符'码相当复杂。你可以(也应该)简单地使用'return r1.name == r2.name && r1.age == r2.age;'。 – 2015-02-08 16:00:07

+0

@KonradRudolph你是对的。 – dude 2015-02-08 16:13:03

回答

1

没有你想要的东西像

if ((*fn)(c->value,value)) {...} 

还,我建议传递的参数为const引用。

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

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==


其实我也建议,对于语义而言,自动默认为您hasValue定义使用std::equal_to如果比较没有明确定义:

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