c++11:unordered_map和pair合用的坑

本文探讨了在使用std::unordered_map进行std::pair插入时遇到的编译错误,并提供了两种解决方案:一是将unordered_map替换为map;二是自定义hash结构或使用boost库来解决hash问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

事情是这样的,

今天在编译的时候报错,很长,报错的地方是std::unordered_map的insert操作,但换成stdmap就没问题,

大概是跟std::unordered_map和std::pair有关,我截取几段,

error: no matching function for call to ‘std::pair<key, std::_List_iterator<long long int> >::pair(const key&, std::_List_iterator<long long int>&)’
       return __pair_type(std::forward<_T1>(__x), std::forward<_T2>(__y));
 error: no matching function for call to ‘std::unordered_map<long long int, std::pair<key, std::_List_iterator<long long int> > >::insert(std::pair<long long int, std::pair<key, std::_List_iterator<long long int> > >)’
         auto res_pair = xxx.insert(std::make_pair(key,std::make_pair(key,value)));

报错的原因是,

std::map底层数据结构是红黑树,

std::unordered_map底层是hash,

而unordered_map没有专门的hash提供给std::pair,

所以一定要用std::pair的话,把unordered_map换成map,不考虑排序的话损失些性能。

或者给std::pair传如一个hash结构。

// unordered_map源码
template<class _Key, class _Tp,
	   class _Hash = hash<_Key>,
	   class _Pred = std::equal_to<_Key>,
	   class _Alloc = std::allocator<std::pair<const _Key, _Tp> > >
class unordered_map
{
    。。。。。
}

自己定一个hash结构,然后传给std::pair

struct pair_hash
{
    template <class T1, class T2>
    std::size_t operator() (const std::pair<T1, T2> &pair) const
    {
        return std::hash<T1>()(pair.first) ^ std::hash<T2>()(pair.second);
    }
};

int main()
{
    std::unordered_map<std::pair<sd::string, std::string>, int, pair_hash> map_pair;
}

或用booost库:boost::hash<>

typedef std::pair<std::string,std::string> self_pair;
std::unordered_map<self_pair,int,boost::hash<self_pair>> unordered_map;

### C++ 中 `std::unordered_map` 的使用方法 #### 创建初始化 `std::unordered_map` 可以创建一个空的 `std::unordered_map` 或者通过初始列表来填充它。 ```cpp #include <iostream> #include <unordered_map> int main() { // 创建一个空的 unordered_map std::unordered_map<int, std::string> map; // 插入键值对 map.insert({1, "one"}); map.emplace(2, "two"); // 使用初始列表创建并赋初值 std::unordered_map<int, std::string> initMap = {{3, "three"}, {4, "four"}}; } ``` #### 访问元素 可以通过下标操作符访问已存在的键对应的值;如果该键不存在,则会自动插入一个新的默认构造的值。 ```cpp // 假设已经有一个名为 myMap 的 std::unordered_map<int, double> double value = myMap[key]; // 如果 key 存在则返回对应值,否则插入新项并将 value 设为0.0[^1] ``` #### 迭代遍历 迭代器用于顺序访问容器内的所有元素。注意这里的顺序是没有定义过的,因为哈希表不保持任何特定顺序。 ```cpp for (auto& pair : map) { std::cout << "{" << pair.first << ": " << pair.second << "}\n"; } ``` #### 查找与删除 提供了成员函数如 `find()` 来定位指定键的位置以及 `erase()` 函数移除单个或多个条目。 ```cpp if (map.find(key) != map.end()) { // 键存在时的操作... } // 删除某个具体的键 map.erase(specificKey); // 清空整个映射 map.clear(); ``` #### 处理冲突 虽然内部实现细节通常由标准库处理,但在某些情况下可能需要考虑负载因子(load factor),即桶的数量相对于存储项目数的比例。当这个比例过高时可能会降低效率,因此有时有必要调整最大负载因子以优化性能。 ```cpp float currentLoadFactor = map.load_factor(); // 获取当前负载因子 size_t bucketCount = map.bucket_count(); // 获取桶数量 map.max_load_factor(0.75f); // 设置新的最大负载因子 map.rehash(bucketCount * 2); // 请求至少两倍于现有桶数的新桶数目 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值