C++中如何修改std::list内tuple的值?迭代修改不持久问题咨询
问题根源&解决方案
嘿,我一眼就揪出问题所在了——你这是踩了C++按值传参的大坑!
你看函数签名里的std::list<std::tuple<SpecialAttack*, int>> attacks,这是按值传递,意味着函数里拿到的attacks是原列表的一个完整副本。你在循环里修改的都是这个副本里的元素,等函数执行完退出,副本直接被销毁,原列表当然纹丝不动啦!
第一步:改成引用传参
先把函数参数改成非const引用,这样函数里操作的就是原列表本身:
void implement_Special_Attacks(std::list<std::tuple<SpecialAttack*, int>>& attacks)
就加个&这么简单,之后你在函数里的所有修改都会直接作用在原列表上,退出函数后修改自然就持久化了。
第二步:正确处理遍历+删除的迭代器
另外,你提到遍历过程中会删除元素,这里得提醒你std::list的迭代器规则:调用erase会让当前迭代器失效,但它会返回下一个有效的迭代器。所以正确的遍历+更新+删除写法应该是这样的(结合你的需求调整):
void implement_Special_Attacks(std::list<std::tuple<SpecialAttack*, int>>& attacks) { auto it = attacks.begin(); while (it != attacks.end()) { // 用引用直接获取tuple里的int,修改时直接作用在原元素上 int& current_count = std::get<1>(*it); SpecialAttack* attack_ptr = std::get<0>(*it); // 用你的SpecialAttacks仿函数判断是否要删除当前元素 if (SpecialAttacks{}(*it)) { // 这里根据你的实际调用逻辑调整 // 删除后,it自动指向下一个有效元素 it = attacks.erase(it); } else { // 更新tuple里的值,比如计数减1 current_count -= 1; // 手动移动到下一个迭代器 ++it; } } }
这里要注意,修改tuple里的int时,一定要用std::get<1>(*it)的引用,不然你修改的只是一个临时拷贝,等于白忙活。
额外提醒
- 确保
SpecialAttack*指向的对象在遍历过程中是有效的,别出现悬空指针的情况。 - 如果你的
SpecialAttacks仿函数需要修改tuple内容,现在传引用后它操作的也是原列表的元素,没问题了。
总之,最核心的修复就是把参数改成引用,剩下的就是迭代器的正确使用姿势,搞定这俩问题你的修改就能持久化啦!
内容的提问来源于stack exchange,提问作者Arabella Turner
相关产品推荐
相关产品推荐

