获取std::find_if返回迭代器解引用后的对象引用是否可行?
问题解答
1. &*组合写法的合规性
你用的&*组合,在确实找到匹配元素的时候是合法的,但存在致命隐患:如果std::find_if没找到对应id的元素,会返回myStuff.end()——而end()迭代器并不指向任何有效元素,这时候解引用它(*end())属于C++里的未定义行为,程序可能直接崩溃,或者出现各种莫名其妙的错误。所以这种写法绝对不安全,不能这么用。
2. 更靠谱的实现方式
正确的思路是先拿到std::find_if返回的迭代器,先判断它是不是end(),再做修改,代码清晰又安全:
void EditSomeThing(uint32_t id, const std::string& newName) { auto it = std::find_if(myStuff.begin(), myStuff.end(), [id](const MyStruct& ms) { return ms.id == id; }); if (it != myStuff.end()) { it->name = newName; } }
另外,如果你的业务场景里需要频繁根据id查找元素,可以考虑把容器换成std::unordered_map<uint32_t, MyStruct>,用id当键。这样查找的时间复杂度从vector的O(n)降到O(1),效率提升很多:
#include <unordered_map> std::unordered_map<uint32_t, MyStruct> myStuffMap; void EditSomeThing(uint32_t id, const std::string& newName) { auto it = myStuffMap.find(id); if (it != myStuffMap.end()) { it->second.name = newName; } }
不过要注意,这种map容器要求id是唯一的,如果允许同一个id对应多个MyStruct对象,那还是得用vector。
内容的提问来源于stack exchange,提问作者PotatoMan
相关产品推荐
相关产品推荐

