使用自定义比较器功能作为模板参数的编译器错误

时间:2019-03-05 02:43:57

标签: c++ compiler-errors

我无法让Heap类接受Comparator作为第二个模板参数。编译器一直在尝试实例化Comparator对象。为什么?我想要的只是两个提供的输入之间的比较。这是编译器错误:

  In file included from main.cpp:1:0:
Heap.hpp: In instantiation of ‘void Heap<T, Cmp>::bubbleUp(size_t) [with T = long unsigned int; Cmp = Comparator<long unsigned int>; size_t = long unsigned int]’:
Heap.hpp:29:35:   required from ‘void Heap<T, Cmp>::insert(const T&) [with T = long unsigned int; Cmp = Comparator<long unsigned int>]’
main.cpp:7:15:   required from here
Heap.hpp:119:9: error: no matching function for call to ‘Comparator<long unsigned int>::Comparator(__gnu_cxx::__alloc_traits<std::allocator<long unsigned int> >::value_type&, __gnu_cxx::__alloc_traits<std::allocator<long unsigned int> >::value_type&)’
         if (Cmp(fArray[idx], fArray[getParent(idx)]))
         ^
Heap.hpp:119:9: note: candidates are:
Heap.hpp:128:7: note: constexpr Comparator<long unsigned int>::Comparator()
 class Comparator

这是课程

#pragma once
#include <vector>
#include <functional>
#include <assert.h>
#include "boost/optional.hpp"

template <typename T, typename Cmp>
class Heap
{

  public:
    Heap()
        : fArray()
    {
    }
    ~Heap() {}
    void insert(const T &toInsert)
    {
        fArray.push_back(toInsert);
        bubbleUp(fArray.size() - 1);
    }


  private:
    std::vector<T> fArray;
    size_t getParent(size_t i) const
    {
        assert(i / 2 < fArray.size());
        return i / 2;
    } 


    void bubbleUp(size_t idx)
    {
        if (idx == 0)
        {
            return;
            // return early if root
        }
        // If heap property violated, swap and recurse upwards
        if (Cmp(fArray[idx], fArray[getParent(idx)])
        {
            std::iter_swap(fArray.begin() + idx, fArray.begin() + getParent(idx));
            bubbleUp(getParent(idx));
        }
    }
};

这是比较器:

template <typename T>
class Comparator
{
  public:
    bool operator()(const T &o1, const T &&o2)
    {
        return o1 < o2;
    }
};

这是主要功能

int main(){
    Heap< size_t,Comparator<size_t> >  h;
    h.insert(4);
    h.insert(5);
    h.insert(6);
    h.insert(3);
}

1 个答案:

答案 0 :(得分:2)

您在这里调用比较器:

if (Cmp(fArray[idx], fArray[getParent(idx)])

Cmp是您的比较器类。这是模板参数,您可以将其指定为Comparator模板实例。

现在,暂时搁置模板主题。实际上,Cmp是此处的类。假设这是一个普通的普通类:

class Cmp {

 // ...
};

现在,问问自己,会表达什么:

Cmp(fArray[idx], fArray[getParent(idx)])

是什么意思?

当然,这意味着:构造Cmp类的临时实例,并将两个参数传递给Cmp的构造函数。

现在,您应该能够理解您的问题了。您的比较器类没有带有两个参数的构造函数。那就是您的编译器告诉您的。

您的比较器类具有重载的()运算符。

在您的用例中,构造一个临时对象没有任何意义。这里的明显目的是为Heap模板建模,并以与标准C ++库的容器使用比较器类相似的方式使用它。

从广义上讲,标准C ++库的容器实际上所做的是,它们声明一个类成员,该类成员是比较器类的实例,然后调用该类成员的()运算符重载。

这可以轻松地转换为您的Heap模板,声明一个私有类成员:

private:
    Cmp cmp;

然后调用该类成员的()运算符重载。

if (cmp(fArray[idx], fArray[getParent(idx)])

另外,请注意,标准C ++库容器通常具有重载的构造函数,该构造函数采用比较器类的显式实例,然后使用它来复制构造其专用比较器实例。