我是否需要在 K 类上进行完整排序才能使用 std::map<K>

Do I need a full ordering on class K to use std::map<K, L>

本文关键字:std gt map lt 是否 排序      更新时间:2023-10-16

可能的重复项:
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的一个特点是它保持其内容的排序顺序,但要实现这一目标,它需要知道如何比较项目。

有三个选项来实现比较方法:

  1. 在 K 中添加operator<定义
  2. 制作一个知道如何比较两个 K 元素的comp函子,并将其添加为模板参数map<K, float, comp> m;

    struct comp {
        bool operator()(const K& first, const K& second) {
            /*****/
        }
    };
    
  3. 您可以定义 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 以来,如果适合您的问题空间,您可以自由地为其提供自己的哈希函数。