我无法让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);
}
答案 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 ++库容器通常具有重载的构造函数,该构造函数采用比较器类的显式实例,然后使用它来复制构造其专用比较器实例。