【问题标题】:C++ Template class function as template parameterC++模板类函数作为模板参数
【发布时间】:2015-07-24 07:30:43
【问题描述】:

在我需要创建一个数据结构(为类型参数化为一个普通的模板,这部分没问题),但还有一个我想作为模板参数传递的比较函数。 如何实施? 谢谢

编辑:请求的伪代码(在 cmets 中)

template <class T, "syntax for the compare function?">
class myclass
{ 
'I have to refer in some way to the compare function here?'
... }

myclass:: myfunctionusingcomparefunction(){
  if('how to use the compare function here?'){...
}else{...}
}

EDIT2:更好的解释

我要问的是如何实现一个能够与模板类型的元素进行比较(或应用函数)的类。 我提到了标准模板类的优先级队列类,因为它允许选择一个覆盖 operator() 的模板类来比较元素(这在有序插入中是必需的): 在 std::priority_list 情况下,第二个模板参数是比较器类。

priority_list<ObjectType, ObjectComparatorType> myQueue;

【问题讨论】:

  • 我不确定你在问什么。 std::priority_queue 已经允许你指定一个比较函数作为它的第三个模板参数。
  • 是的,我只是举个例子。我想对我的班级做这样的事情,因为我想将一个比较函数传递给一个班级,我会知道正确的语法以及如何处理它@MilesBudnek
  • 写一些伪代码
  • @Daniel 点击链接并从那里复制原型。或者在您的硬盘驱动器(或只是编译器安装的头文件)中搜索名为queue 的文件,然后您就可以确切地看到它是如何工作的。或者找到相同的online
  • @Potatoswatter 好的,谢谢,我现在检查

标签: c++ templates priority-queue standard-library


【解决方案1】:

基本上,只要有一个比较函数类型的成员,并有一个可以引用该类型的构造函数,这样对象就可以在需要时传递一个函数指针/lambda/std::function。以下是 GNU libstdc++ 对std::priority_queue 的处理方式(去掉了不相关的部分):

template <class _Tp, class _Sequence = vector<_Tp>, 
          class _Compare = less<typename _Sequence::value_type> >
class  priority_queue {
protected:
  _Sequence c;
  _Compare comp;
public:
  explicit priority_queue(const _Compare& __x) :  c(), comp(__x) {}

【讨论】:

    【解决方案2】:

    好的,考虑到优先级列表的示例,我的问题的解决方案如下:我的模板类采用三个模板参数,priority_queue 对象的类型,优先级对象的类型和比较器类必须覆盖 operator() 来比较优先级对象。 比较器类的一个对象在比较器类的构造函数中给出

    priorityQueue.hpp

    template <class T, class Prio, class Comp>
    class priorityQueue{
        template <class T, class Prio>
        class Node{
            T elem;
            Node *next;
            Prio priority;
    
            public:
            Node(T e, int p) : elem(e), priority(p) {}
        };
    
        /*class priorityExc{
        public:
            const char* what(){ return "Priority must be in [0, 10]";}
        };*/
    
        class emptyExc{
        public:
            const char* what(){ return "No element to remove";}
        };
    
    
        Node<T, Prio> *head;
        int len;
        Comp comparator; //must overload the operator()
    
        public:
        priorityQueue(Comp cmp) : comparator(cmp), len(0) {}
        void insert (T myElem, Prio myPriority);// throw (priorityExc);
        T remove() throw (emptyExc);
    };
    

    使用这种方法,insert 方法的一个实现,它以优先顺序的方式在队列中插入一个元素,可能如下:

    template <class T, class Prio, class Comp>
    void priorityQueue<T, Prio, Comp>::insert(T myElem, Prio myPriority) //throw (priorityExc)
    {
        //if(myPriority > 10 || myPriority < 0) throw priorityExc;
        Node<T, Prio> *node = new Node(myElem, myPriority);
        if(head == 0){
            head = node;
            head->next = 0;
        }
        else{
            Node *temp = head, *p = head;
            while(comparator(temp->priority, node->priority) > 0){
                p = temp;
                temp = temp->next;
            }
            p->next = node;
            node->next = temp;
        }
    }
    

    【讨论】: