You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将存在值重复的enum class作为map的唯一键?

解决枚举类成员值重复时作为map唯一键的问题

std::map默认用std::less<T>比较键,枚举类的比较逻辑基于底层整数值,所以值相同的成员会被视为同一键。要让每个枚举成员(无论值是否重复)都作为唯一键存储,有以下几种可行方案:

方案一:自定义比较器适配std::map

自定义比较器,给每个枚举成员分配唯一标识,通过比较标识区分不同成员。

示例代码:

#include <map>
#include <vector>

enum class SomeEnum
{
    A = 1,
    B = 2,
    C = 2
};

struct EnumUniqueComparator {
    bool operator()(SomeEnum lhs, SomeEnum rhs) const {
        auto get_unique_id = [](SomeEnum e) {
            switch(e) {
                case SomeEnum::A: return 0;
                case SomeEnum::B: return 1;
                case SomeEnum::C: return 2;
                default: return -1;
            }
        };
        return get_unique_id(lhs) < get_unique_id(rhs);
    }
};

int main() {
    std::map<SomeEnum, std::vector<int>, EnumUniqueComparator> my_map;
    
    my_map[SomeEnum::A].push_back(10);
    my_map[SomeEnum::B].push_back(20);
    my_map[SomeEnum::C].push_back(30);
    
    // 三个枚举成员会被作为独立键存储
    return 0;
}

如果枚举成员较多,可用宏简化ID分配:

#define ENUM_ID_MAPPING(ENUM) case SomeEnum::ENUM: return __COUNTER__;

struct EnumUniqueComparator {
    bool operator()(SomeEnum lhs, SomeEnum rhs) const {
        auto get_unique_id = [](SomeEnum e) {
            switch(e) {
                ENUM_ID_MAPPING(A)
                ENUM_ID_MAPPING(B)
                ENUM_ID_MAPPING(C)
                default: return -1;
            }
        };
        return get_unique_id(lhs) < get_unique_id(rhs);
    }
};

__COUNTER__是编译器内置宏,每次调用自动生成递增的唯一整数,新增枚举成员时只需添加一行ENUM_ID_MAPPING(成员名)即可。

方案二:自定义哈希与相等判断适配std::unordered_map

如果偏好无序哈希表,可给std::unordered_map自定义哈希函数和相等判断规则,同样基于枚举成员的唯一标识。

示例代码:

#include <unordered_map>
#include <vector>
#include <functional>

enum class SomeEnum
{
    A = 1,
    B = 2,
    C = 2
};

struct EnumUniqueHash {
    size_t operator()(SomeEnum e) const {
        switch(e) {
            case SomeEnum::A: return 0;
            case SomeEnum::B: return 1;
            case SomeEnum::C: return 2;
            default: return std::hash<int>()(-1);
        }
    }
};

struct EnumUniqueEqual {
    bool operator()(SomeEnum lhs, SomeEnum rhs) const {
        return EnumUniqueHash{}(lhs) == EnumUniqueHash{}(rhs);
    }
};

int main() {
    std::unordered_map<SomeEnum, std::vector<int>, EnumUniqueHash, EnumUniqueEqual> my_umap;
    
    my_umap[SomeEnum::A].push_back(10);
    my_umap[SomeEnum::B].push_back(20);
    my_umap[SomeEnum::C].push_back(30);
    
    return 0;
}

备选方案:修改枚举定义(若允许)

如果可以修改原枚举的定义,直接给每个成员分配唯一的底层值,就能直接使用默认的map容器,无需额外适配:

enum class SomeEnum
{
    A = 1,
    B = 2,
    C = 3 // 改为唯一值
};

// 直接使用默认std::map即可
std::map<SomeEnum, std::vector<int>> my_map;

内容的提问来源于stack exchange,提问作者steep

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 06:34:52