C++自定义键的map模板insert失效问题求助
问题根源:Domain的
operator<不符合严格弱序要求 你遇到的问题核心在于**Domain结构体的<运算符重载逻辑错误**,导致std::map无法正确识别相同的Domain键,进而使得插入操作看似"无效"——实际上数据被插入到了另一个被错误判定为不同键的位置,而你每次访问的都是新创建的空集合。
为什么原代码会失败?
std::map依赖严格弱序的比较规则,要求对于任意两个对象a和b:
- 如果
a < b为真,那么b < a必须为假 - 如果
a < b为假且b < a为假,则a和b被视为相等(map会把它们当作同一个键)
你的原比较逻辑:
bool operator< (Domain const &domain) const { return i < domain.i || j < domain.j || q < domain.q; }
完全不符合这个规则。举个典型反例:
- 假设
a = Domain("A", "B", 0),b = Domain("B", "A", 0) - 按照你的逻辑,
a < b会因为a.i < b.i返回true - 但
b < a会因为b.j < a.j也返回true
这就违反了严格弱序的核心要求,导致map内部排序混乱,无法正确判断键的唯一性。
在你的场景中,每次调用ITV[Domain(PairStr,q)]时,map都无法识别这是已经存在的键,所以每次都会创建一个新的空set<pair<int,int>>,而你之前插入的数据被存在了另一个键对应的集合里,所以打印的永远是新集合的大小0。
修复方案:正确实现严格弱序的<运算符
你需要按照成员的优先级依次比较,而不是用逻辑或连接。有两种简洁可靠的写法:
写法1:手动依次比较
bool operator< (Domain const &domain) const { // 先比较i,i不同则直接返回结果 if (i != domain.i) { return i < domain.i; } // i相同,再比较j if (j != domain.j) { return j < domain.j; } // i和j都相同,最后比较q return q < domain.q; }
写法2:利用std::tie简化代码
std::tie会把多个成员打包成一个元组,元组的<运算符天然符合严格弱序规则(需要额外包含<tuple>头文件):
#include <tuple> bool operator< (Domain const &domain) const { return std::tie(i, j, q) < std::tie(domain.i, domain.j, domain.q); }
修复后的效果
替换Domain的<运算符后,运行代码会完全符合你的预期输出:
Size of A-B at 0: 1 Size of A-B at 1: 1 Size of A-B at 1: 2 Size of A-B at 1: 3 Size of B-DES at 1: 1 Size of B-DES at 1: 2 Size of INI-A at 0: 1 Size of INI-A at 1: 1 Size of INI-A at 1: 2
内容的提问来源于stack exchange,提问作者Daniel Ramón Lumbierres
相关产品推荐
相关产品推荐

