c++ - Compiler error with custom comparator function as template argument
问题描述
I can't get the Heap class to accept the Comparator as the second template argument. The compiler keeps trying to instantiate a Comparator object. Why? All I want is a comparision between the 2 provided inputs. Here's the compiler error:
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
Here's the class
#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));
}
}
};
Here's the comparator:
template <typename T>
class Comparator
{
public:
bool operator()(const T &o1, const T &&o2)
{
return o1 < o2;
}
};
Here's the main function
int main(){
Heap< size_t,Comparator<size_t> > h;
h.insert(4);
h.insert(5);
h.insert(6);
h.insert(3);
}
解决方案
你在这里调用你的比较器:
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++ 库容器通常具有一个重载的构造函数,该构造函数采用比较器类的显式实例,然后使用它来复制构造它们的私有比较器实例。
推荐阅读
- python - 从 Win32 二进制文件调用匿名 C 函数
- django - 如何在 Django 模型中为继承的模型类字段设置一些值?
- javascript - 我想在循环中的所有查询完成后返回结果(express.js、react.js、mysql)
- android - 无法通过 android studio 在 google 日历中创建事件
- c# - 在 C# 中将字符串的一部分转换为日期时间
- sql - SQLite - 如何从一个表中选择不在另一个表中的记录
- excel - 以编程方式设置链接到单元格值的文本框
- pytorch - 从 torchvision 下载数据集。论点之间的差异?
- java - 查找足球锦标赛中所有比赛的所有可能结果
- python - 有没有办法使用 Python 跳过读取 Excel 合并单元格中的空单元格?