Passing compare function for a generic class

点点圈 提交于 2019-12-13 02:49:45

问题


I want to create a priority queue for which I am using a heap(using array).The priority queue will be generic thus accept all data types as long as the client pass a compare function through constructor to compare the two types.

How can I create a constructor that will accept the compare function as a parameter? Moreover how can I make the compare function to be called when I check

return (Type a==Type b)

Eg.

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

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

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

The PQueue class is implemented as an array. As the adding,bubbling-up, heapifying needs to compare two ValType I want them to compare using compareNode.


回答1:


You don't have to do this: don't use an array, use the built-in priority-queue of the STL library in c++. It has its own compare function which you can alter.

Reference: http://www.cplusplus.com/reference/queue/priority_queue/

You can also see topcoder tutorials (for algorithmic usage).




回答2:


Let me first give you a simple answer and then a more versatile one.

You can simply pass a function as parameter by declaring the type of that parameter to be the type of pointer function. You can also have variables of type pointer to function. For instance, if the declaration of your function is

int compareNode(node a, node b)

then you could do something like this:

#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

Hope this you can use this.

Now to the more versatile example.

C++11 introduces lambdas. http://www.cprogramming.com/c++11/c++11-lambda-closures.html http://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 You need to compile this code for C++11 standard.

Here the template Comparator can be both pointer to function and lambda. If you are interested in lambdas, the two links I provided above should get you started.



来源:https://stackoverflow.com/questions/17512705/passing-compare-function-for-a-generic-class

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!