如何在std::map中使用结构体指针并以两个int作为键?
解决std::map使用双int键存储结构体指针的问题
首先,你遇到的错误根源有两个:一是**std::map的模板参数顺序完全搞错了**,二是想用[1,5]这种方式传递双键的写法在C++里不合法。让我一步步帮你拆解问题并给出正确方案:
1. 先搞懂错误原因
你写的std::map<int, int, my_struct*>不符合std::map的模板定义——std::map的模板参数规则是:
template< class Key, class T, class Compare = std::less<Key>, class Allocator = std::allocator<std::pair<const Key, T>> > class map;
第三个参数是键的比较器(默认是std::less<Key>),而你把my_struct*放在了这个位置,编译器自然会认为你要把结构体指针当作比较函数,于是报错说“my_struct *不是函数或函数指针”。
另外,my_map[1,5]里的逗号是C++的逗号运算符,它会先计算1然后直接丢弃,最终等价于my_map[5],这完全不是你想要的双键效果。
2. 最直接的解决方案:用std::pair作为双键
无需自定义额外代码,直接用std::pair<int, int>作为std::map的键类型,就能把两个int组合成一个合法的键:
步骤1:正确定义map
#include <map> #include <utility> // 用于std::pair和std::make_pair struct my_struct { /* 你的结构体定义 */ }; // 正确的map定义:键是pair<int,int>,值是my_struct* std::map<std::pair<int, int>, my_struct*> my_map;
步骤2:插入/访问元素
在C++11及以后的版本里,你可以用列表初始化直接构造pair:
my_struct* test1 = get_struct_ptr(); // 用列表初始化构造双键 my_map[{1, 5}] = test1;
如果需要兼容C++11之前的版本,就用std::make_pair:
my_map[std::make_pair(1, 5)] = test1;
3. 可选方案:自定义键结构体
如果你觉得std::pair不够直观,也可以自定义一个结构体作为键,只要给它重载<运算符(因为std::map需要键支持排序比较):
步骤1:定义键结构体并重载<
struct DoubleKey { int first; int second; // 重载<运算符,定义键的比较规则 bool operator<(const DoubleKey& other) const { // 先比较first,first相等再比较second if (first != other.first) { return first < other.first; } return second < other.second; } };
步骤2:定义并使用map
std::map<DoubleKey, my_struct*> my_map; // 插入元素 my_struct* test1 = get_struct_ptr(); my_map[{1, 5}] = test1; // 或者显式构造DoubleKey my_map[DoubleKey{1, 5}] = test1;
总结
- 别搞错
std::map的模板参数顺序:键类型是第一个参数,值类型是第二个 - 双int键可以用
std::pair<int,int>快速实现,或者自定义结构体并重载< - 访问时用列表初始化或
std::make_pair构造双键,不要用逗号运算符
内容的提问来源于stack exchange,提问作者Jason
相关产品推荐
相关产品推荐

