为什么我不能重载我传递给 std::upper_bound 的比较器
Why can't I overload this comparator that I pass to std::upper_bound
我对C++相当陌生,认为重载函数总是可以的,我所说的重载是指:
C++中的函数重载您可以在同一范围内对同一函数名进行多个定义。函数的定义必须因参数列表中参数的类型和/或数量而异。不能重载仅因返回类型不同而不同的函数声明。
然而,当我编写下面的代码时,它不会编译,我的印象是std::upper_bound无法解析它应该使用哪个比较器,尽管这看起来很容易,因为只有一个具有正确签名。
EDIT这些函数位于命名空间中的实用程序文件(而非类)中。
我在这篇文章之后做了这件事
我可能完全错了,你能解释一下吗
- 为什么代码不编译
- 我如何编写lt的两个实现,哪个不同的签名将使代码可编译和运行
#include <iostream>
#include <string>
#include <vector>
#include <cmath>
#include <algorithm>
//I have a utility file where functions are defined in a namespace
namespace util{
bool lt(double y, const std::pair<double, long>& x) {
return x.first < y;
}
//If this function is commented the whole will compile and run
bool lt(const std::pair<double, long>& x, double y) {
return x.first < y;
}
}
int main()
{
std::vector<std::pair<double,long> > v;
v.push_back(std::make_pair(999., 123));
v.push_back(std::make_pair(100., 3));
v.push_back(std::make_pair(15., 13));
v.push_back(std::make_pair(10., 12));
v.push_back(std::make_pair(1., 2));
//use upper_bound
std::vector<std::pair<double,long> >::iterator it =
std::upper_bound(v.begin(), v.end(), 25., util::lt);
std::cout << " it->first => " << it->first << std::endl;
}
调用upper_bound
的地方不是lt
的调用站点,因此这里没有进行过载解决,并且您的过载是不明确的。
#include <algorithm>
#include <cmath>
#include <iostream>
#include <string>
#include <vector>
bool lt(const std::pair<double, long>& x, const std::pair<double, long>& y)
{
return x.first < y.first;
}
int main()
{
std::vector<std::pair<double, long>> v;
v.push_back(std::make_pair(999., 123));
v.push_back(std::make_pair(100., 3));
v.push_back(std::make_pair(15., 13));
v.push_back(std::make_pair(10., 12));
v.push_back(std::make_pair(1., 2));
// use upper_bound
std::vector<std::pair<double, long>>::iterator it =
std::upper_bound(v.begin(), v.end(), std::make_pair(25., 0.), lt);
std::cout << " it->first => " << it->first << std::endl;
}
因为std::upper_bound
是谓词类型(您正在传递的函数)的模板,所以在查看任何upper_bound
主体之前,必须知道要使用的特定重载(这是可以执行重载解析的地方,因为参数是已知的)。有各种各样的方法来解决这个问题,没有一种特别漂亮:
-
转换为确切类型:
std::upper_bound(v.begin, v.end(), 25.0, static_cast<bool (*)(double, const std::pair<double, long>&>(lt))
-
用lambda:包装调用
[](auto x, auto y){ return lt(x, y); }
-
将函数放入一个类中,以便使用类的类型实例化模板,然后在模板的主体中进行重载解析:
struct LT { bool operator()(double y, const std::pair<double, long>& x) { return x.first < y; } bool operator()(const std::pair<double, long>& x, double y) { return x.first < y; } }; // ... std::upper_bound(v.begin(), v.end(), 25.0, LT());
注意,后两个选项几乎是一样的!
事实上,我建议你停下来想想你在做什么。在两种完全不同的类型之间提供订购真的有意义吗?你的第一个函数实际上似乎是实现gt
(大于),也许它应该是return y < x.first;
?
我还真的认为使用endl
是一种糟糕的做法(我知道不是每个人都同意我的观点)。
相关文章:
- std::设置自定义比较器
- C++中"std::sort"比较器的不同类型
- 将 std::set 与基于键的比较器一起使用
- 带自定义比较器的最小优先级队列
- 函数类作为比较器
- 优先级队列自定义比较器
- 什么是自定义比较器以及如何在 C++ 的排序函数中使用它?
- 没有默认构造函数作为模板参数的自定义比较器
- set_intersection使用自定义设置比较器
- 如何为集合 c++ 建立比较器
- C++复杂情况的比较器通过参数问题
- 对于BTreeMap和其他依赖于Ord的东西,是否有等效于C++比较器对象?
- 对没有比较器或λ函数的向量进行排序?
- "operator()"在重载运算符方法中是什么意思,在priority_queue(STL)中用作C++中的比较器?
- 用户定义的结构是否有默认C++比较器?
- C++设置了一个用于排序的比较器和另一个用于唯一性的比较器
- 使用迭代器的自定义比较器函数
- C++对λ比较器EXC_BAD_ACCESS进行排序
- 如果要求比较器是严格的总排序,而不仅仅是严格的弱排序,C++标准算法会更快吗?
- Cython中带有自定义比较器的优先级队列