【问题标题】:Passing compare function for a generic class为泛型类传递比较函数
【发布时间】:2013-07-07 13:46:24
【问题描述】:

我想创建一个使用堆(使用数组)的优先级队列。优先级队列将是通用的,因此只要客户端通过构造函数传递一个比较函数来比较这两种类型,就可以接受所有数据类型。

如何创建一个接受比较函数作为参数的构造函数?此外,如何在我检查时调用比较函数

return (Type a==Type b)

例如。

struct node{
   string val1;
   string val2;
   vector<node *> connectedNodes;
};

int compareNode(node a,node b){
 //describe the compare
}

int main(){
PQueue<node> q(compareNode);
}

PQueue 类被实现为一个数组。由于添加、冒泡、堆化需要比较两个 ValType,我希望它们使用 compareNode 进行比较。

【问题讨论】:

  • 在切换到 C++ 时放弃 Java 思维方式是有益的(反之亦然)。对于 C++ 模板尤其如此,它的功能远远优于 Java 泛型。在 C++ 中,您的模板可以引用在类型上定义的运算符,因此您可以编写 a &lt; b,只要在您的类型的对象上定义了 &lt; 运算符,模板就会编译。如果您必须在旁边使用比较器,请查看second overload of sort 以了解实现此目的的方法。
  • 但是
  • 是比较两种类型,还是比较两种类型的两个实例?术语在这里很重要。
  • 我已经编辑了这个问题。我想我想比较两个相同类型的实例

标签: c++ generics constructor compare


【解决方案1】:

您不必这样做:不要使用数组,使用 C++ 中 STL 库的内置优先级队列。它有自己的比较功能,您可以更改。

参考:http://www.cplusplus.com/reference/queue/priority_queue/

您还可以查看 topcoder 教程(用于算法使用)。

【讨论】:

  • 我在学习阶段我想知道所有的数据结构是如何工作的,学习它们的最好方法是创建它们..:-)
【解决方案2】:

我先给你一个简单的答案,然后再给你一个更通用的答案。

您可以通过将参数的类型声明为指针函数的类型来简单地将函数作为参数传递。您还可以将变量类型指针指向函数。例如,如果你的函数声明是

int compareNode(node a, node b)

那么你可以这样做:

#include <iostream>
#include <vector>
#include <string>
using namespace std;

struct node{
   string val1;
   string val2;
   vector<node *> connectedNodes;
};

int compareNode(node a,node b){
 //describe the compare
 return a.val2.compare(b.val2); // or any other code
}

template <class T>
class PQueue {
  protected:
    // this declares a protected member named compareFunction of type pointer to a function which takes 2 T parameters and returns a int. Note that all the parenthesis are mandatory
    int (*compareFunction)(T, T);

  public:

    PQueue (int (*compareFunctionParameter)(T, T)) : compareFunction(compareFunctionParameter) {
       // this constructor receives a pointer to function and initializes it's member to that pointer. If the constructor initialization list confuses you, you can read 'compareFunction = compareFunctionParameter '
    }

  int someMethod() {
     // call the function through the pointer you have:
     node n1, n2;
     n1.val1 = "node1_val1";
     n1.val2 = "zzz";

     n2.val1 = "node2_val1";
     n2.val2 = "aaa";
     return compareFunction(n1, n2);
  }
};

int main() {
    PQueue<node> pq(compareNode);
    cout << pq.someMethod() << endl;
    return 0;
}

http://ideone.com/EPjbya

希望这个你可以用这个。

现在来看一个更通用的例子。

C++11 引入了 lambda。 http://www.cprogramming.com/c++11/c++11-lambda-closures.htmlhttp://www.stroustrup.com/C++11FAQ.html#lambda

#include <iostream>
#include <vector>
#include <string>
#include <functional>
using namespace std;

struct node{
   string val1;
   string val2;
   vector<node *> connectedNodes;
};

int compareNode(node a,node b){
 //describe the compare
 return a.val2.compare(b.val2); // or any other code
}

template <class T, class Comparator>
class PQueue {
  protected:
    Comparator compareFunction;

  public:

    PQueue (Comparator compareFunctionParameter) : compareFunction(compareFunctionParameter) {
    }

  int someMethod() {
     // call the function
     node n1, n2;
     n1.val1 = "node1_val1";
     n1.val2 = "zzz";

     n2.val1 = "node2_val1";
     n2.val2 = "aaa";
     return compareFunction(n1, n2);
  }
};

int main() {
    // queue with pointer to function
    PQueue<node, int (*)(node, node)> pq(compareNode);
    cout << pq.someMethod() << endl;

    // queue with lamda (anonimous function)
    PQueue<node, std::function<int (node, node)>> pq_lambda([](node a, node b) -> int {return a.val1.compare(b.val1);} );
    cout << pq_lambda.someMethod() << endl;
    return 0;
}

http://ideone.com/ryQmAn你需要为C++11标准编译这段代码。

这里的模板 Comparator 既可以是指向函数的指针,也可以是 lambda。如果您对 lambdas 感兴趣,我上面提供的两个链接应该可以帮助您入门。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-05
    • 1970-01-01
    • 2011-04-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多