我是否需要在 K 类上进行完整排序才能使用 std::map<K>
Do I need a full ordering on class K to use std::map<K, L>
可能的重复项:
std::map 键类必须满足哪些要求才能成为有效键?
我想使用std::map
作为从我的班级到另一个班级的地图。如果我尝试以下代码,则会出现错误" undefined operator <
"。这是否意味着我需要在类K
上订购才能使用map
?它必须是完全订购的吗?我是否需要所有四个订购运算符,或者>
就足够了?
#include <iostream>
#include <map>
#include <stdio.h>
using namespace std;
struct K {
int i, j;
K(int i, int j) : i(i), j(j){}
friend bool operator==(const K& x, const K& y){ return (x.i==y.i)&&(x.j==y.j); }
friend bool operator!=(const K& x, const K& y){ return !(x==y); }
/* friend bool operator<(const K&x, const K&y){
if(x.i<y.i) return true;
if(x.i>y.i) return false;
return x.j<y.j;
}
friend bool operator>(const K&x, const K&y){ return y<x; }
friend bool operator<=(const K&x, const K&y){ return !(y<x); }
friend bool operator>=(const K&x, const K&y){ return !(x<y); }
*/
};
int main(){
map<K, float> m;
m[K(1,2)]=5.4;
if(m.find(K(1,2))!=m.end())
cout << "Found: " << m[K(1,2)] << endl;
else
cout << "Not found" << endl;
return 0;
}
是的,你需要一种方法来比较元素(operator<
)才能使用std::map。map的一个特点是它保持其内容的排序顺序,但要实现这一目标,它需要知道如何比较项目。
有三个选项来实现比较方法:
- 在 K 中添加
operator<
定义 -
制作一个知道如何比较两个 K 元素的
comp
函子,并将其添加为模板参数map<K, float, comp> m
;struct comp { bool operator()(const K& first, const K& second) { /*****/ } };
-
您可以定义 K 的 std::less 专用化
template<> struct less<K> { bool operator()(const K& first, const K& second) { /*****/ } };
使用简单map<K, float> m;
这是有效的,因为通过地图的模板定义,比较函数设置为 std::less。
模板 <类键,类>类比较 = 更少, 类分配器 = 类映射>>分配器
映射中的元素由您提供的键类型的比较函数引用。隐式作为std::less
或显式作为第三个模板参数。
如果使用自定义键类型,则还需要提供适当的比较函数(或函数对象),该函数(或函数对象)对键施加严格的弱排序。也就是说,如果键看起来相等
!(key1 < key2 || key2 < key1)
这些项目被视为等效项。
因此,如果比较函数仅提供键的部分顺序,则元素可能被视为相等但实际上不同的元素,因此它们的值可能会相互干扰。
只需定义operator<
为了std::map
订购的目的,其他一切都是不必要的。
一个 std::map 只需要一个运算符<。实现通常使用"红黑"树,该树可以构建为只需要一个<运算符。>
但是,您可以完全按照刚才的方式使用 std::unordered_map。它通常使用通用哈希函数;自 C++11 以来,如果适合您的问题空间,您可以自由地为其提供自己的哈希函数。
- 使用std::multimap迭代器创建std::list
- C++中std::resize(n)和std::shrink_to_fit之间的区别
- 来自 std::list 的迭代器 .end() 按预期返回"0xcdcdcdcdcdcdcdcd"但 .begin()
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 如何导出包含具有"std::unique_ptr"值的"std::map"属性的
- 从持续时间构造std::chrono::system_clock::time_point
- std::具有相同基类的类的变体
- std::向量与传递值的动态数组
- 使用std::vector的OpenCL矩阵乘法
- std::map<struct,struct>::find 找不到匹配项,但是如果我循环通过 begin() 到 end(),我在那里看到匹配项
- std::condition_variable::wait()如何评估给定的谓词
- 如何获取std::result_of函数的返回类型
- std::原子加载和存储都需要吗
- 将对象移动到std::shared_ptr
- std::vector<;uint8_t>;当C++11/14启用时,手动复制而不是调用memcpy
- 是std :: set&lt; std :: future&gt;不可能存在
- 在修改列表后,std :: list&lt; t&gt; :: end()的值是否会更改
- 使用 std::vector<boost::shared_ptr<Base_Class>> 或 boost::p tr_vector 的性能注意事项是什么<Base>
- std::map<std::set, double> AND std:<long>map< std::p air<long, long>, double>
- 如何获取std::vector<DMatch>