2

可能重复:
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;
}
4

4 回答 4

5

的,您需要一种比较元素 ( operator<) 的方法才能使用 std::map。map 的特点之一是它保持其内容的排序,但要实现这一点,它需要知道如何比较项目。

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

  1. operator<在 K 中添加定义
  2. 制作一个comp知道如何比较两个 K 元素的仿函数并将其添加为模板参数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;

这是因为 map 的模板定义将比较函数设置为 std::less。

模板< class Key, class T, class Compare = less , class Allocator = allocator >> class map

于 2012-10-16T13:37:09.183 回答
4

地图中的元素由您提供的 Key 类型的比较函数引用。隐含地std::less或显式地作为第三个模板参数

如果您使用自定义键类型,您还需要提供适当的比较函数(或功能对象),对键施加严格的弱排序。也就是说,如果键看起来相等

!(key1 < key2 || key2 < key1)

这些项目被认为是等效的。

因此,如果您的比较函数仅提供键的部分顺序,则元素可能被认为是相等的,但实际上是不同的,因此它们的值可能会相互干扰。

于 2012-10-16T13:51:03.657 回答
0

只需定义operator<

std::map出于订购的目的,其他一切都是不必要的。

于 2012-10-16T13:38:45.033 回答
-2

std::map 只需要一个 operator<。实现通常使用“红黑”树,可以构建为只需要 < 运算符。

但是,您可以完全按照刚才的方式使用 std::unordered_map。它通常使用通用哈希函数;如果适合 C++11 以来的问题空间,您可以自由地为其提供自己的哈希函数。

于 2012-10-16T13:41:32.927 回答