C++ : 出错解释 base operand of '->' has non-pointer type 'std::pair<int, int>'

本文分析了一段C++代码中出现的错误:尝试使用-&gt;操作符访问std::pair对象成员时引发的编译错误,并详细解释了原因及正确做法。

C++ ERROR : base operand of ‘->’ has non-pointer type ‘std::pair< int, int>’ 的解释

问题描述

出错代码(截取部分):
list<pair<int,int>> cachelist;
unordered_map<int,list<pair<int,int>>::iterator> map;

void put(int key, int value) {
    auto it = map.find(key);
    if(it != map.end()){
        touch(it->second);
        it->second->second = value; // ①
    }
    else if(map.size() < cap){
        cachelist.push_front(make_pair(key,value));
        map[key]=cachelist.begin();
    }
    else{
        auto it = cachelist.back();// ②
        map.erase(it->first); // 出错位置~~!!
        cachelist.pop_back();
        cachelist.push_front(make_pair(key,value));
        map[key]=cachelist.begin();
    }
}
报错内容:

Line xx: base operand of '->' has non-pointer type ' std::pair <int, int>'

分析与解决

  1. 首先unordered_maperase() 函数的参数可以是键值,可以是迭代器,也可以是迭代器区间,那么肯定不是erase()的问题;
  2. 然后报错提示告诉我们pair<int,int>不能用->符号,那就奇怪了,位置①我们不是也用了it->second->second吗?①处的itunordered_mapiteratorit->secondlist<pair<int,int>>iterator,所以it->second->secondpair的第二值,好像没什么不对??
  3. 到这里可能你跟我一样,发现问题了,②处的it并不是list<pair<int,int>>的迭代器,而是cachelist的最后一个元素节点的地址,auto实际上应该是pair<int,int> &,而pair<int,int>是不认识->符号的,所以出错位置的应该把->改成.,即:
map.erase(it.first);

参考链接

http://stackoverflow.com/questions/21058894/error-base-operand-of-has-non-pointer-type-stdpairint-int

<think>好的,我现在遇到了一个C++编译错误,错误信息是:“base operand of->’ has non-pointer type std::weak_ptr<Node<int, std::__cxx11::basic_string<char>>>”。我需要理解这个错误的原因并找到解决办法。 首先,错误提示中的“base operand of->’ has non-pointer type”说明我在使用箭头运算符->的时候,操作的对象不是一个指针类型。而这里提到的类型是std::weak_ptr<Node<...>>,也就是说,我可能直接对一个weak_ptr对象使用了->来访问成员,这是不允许的。 weak_ptr是C++智能指针的一种,它不会增加引用计数,通常用来解决循环引用的问题。但weak_ptr本身并不直接拥有对象,所以不能像shared_ptr或原生指针那样直接使用->或*来访问对象。正确的做法应该是先将weak_ptr转换为shared_ptr,然后再访问成员。 比如,假设我有这样的代码: ```cpp std::weak_ptr<Node<int, std::string>> weakNode; weakNode->someMemberFunction(); // 这里会报错 ``` 这里的weakNode是weak_ptr类型,直接使用->会导致错误。正确的做法应该是先调用lock()方法获取一个临时的shared_ptr,再使用这个shared_ptr来访问成员: ```cpp if (auto sharedNode = weakNode.lock()) { sharedNode->someMemberFunction(); // 正确 } ``` lock()方法会返回一个shared_ptr,如果原来的对象还存在,就有效,否则返回空的shared_ptr。因此在使用前需要检查是否有效,避免悬空指针。 另外,检查代码中是否有其他地方错误地使用了weak_ptr的->操作符,比如在赋值或者函数调用时。例如,可能想通过weak_ptr访问Node的成员,但没有正确转换。 总结错误的原因是对weak_ptr直接使用箭头运算符,而正确的解决方法是使用lock()获取shared_ptr后再访问。同时,需要确保在转换后的shared_ptr有效的情况下使用,避免访问已经被销毁的对象。</think>### C++错误 'base operand of->’ has non-pointer type std::weak_ptr<...>' 的解决方案 #### 错误原因分析 错误信息表明:在使用 `->` 运算符时,操作对象 `std::weak_ptr<...>` 不是指针类型。`std::weak_ptr` 是 C++ 中用于解决循环引用的智能指针,但**不能直接访问其指向的对象**,必须通过 `lock()` 方法转换为 `std::shared_ptr` 后才可访问[^1]。 #### 具体解决步骤 1. **使用 `lock()` 获取临时 `std::shared_ptr`** ```cpp std::weak_ptr<Node<int, std::string>> weakNode; if (auto sharedNode = weakNode.lock()) { // 转换为 shared_ptr 并检查有效性 sharedNode->member_function(); // 正确访问成员 } ``` 2. **错误代码示例与修正** ```cpp // 错误示例:直接对 weak_ptr 使用 -> weakNode->value; // 正确示例:通过 lock() 转换 if (auto ptr = weakNode.lock()) { ptr->value; } ``` 3. **验证 weak_ptr 有效性** ```cpp if (!weakNode.expired()) { // 检查对象是否已被释放 auto ptr = weakNode.lock(); ptr->do_something(); } ``` #### 应用场景示例 在双向链表或树结构中,若父节点持有子节点的 `std::shared_ptr`,子节点需持有父节点的 `std::weak_ptr` 以避免循环引用: ```cpp struct Node { std::shared_ptr<Node> child; std::weak_ptr<Node> parent; // 使用 weak_ptr 避免循环引用 void print_parent() { if (auto p = parent.lock()) { // 必须转换后使用 std::cout << p->value; } } }; ``` #### 关键注意事项 - **生命周期管理**:`lock()` 返回的 `shared_ptr` 可能为空,需检查有效性。 - **线程安全**:多线程环境中需确保 `weak_ptr` 和 `shared_ptr` 的原子性操作。 - **设计原则**:优先用 `weak_ptr` 替代 `shared_ptr` 打破循环引用[^1]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值