C++通过值删除vector元素编译报错求助
问题:vector元素按值删除编译错误
我参考Stack Overflow教程实现了一个按值删除vector元素的模板函数,但编译时报错,错误信息如下:
/usr/include/c++/11/bits/predefined_ops.h: In instantiation of ‘bool __gnu_cxx::__ops::_Iter_equals_val<_Value>::operator()(_Iterator) [with _Iterator = __gnu_cxx::__normal_iterator<Types::segment*, std::vector<Types::segment> >; _Value = const Types::segment]’: /usr/include/c++/11/bits/stl_algo.h:822:13: required from ‘_ForwardIterator std::__remove_if(_ForwardIterator, _ForwardIterator, _Predicate) [with _ForwardIterator = __gnu_cxx::__normal_iterator<Types::segment*, std::vector<Types::segment> >; _Predicate = __gnu_cxx::__ops::_Iter_equals_val<const Types::segment>]’ /usr/include/c++/11/bits/stl_algo.h:860:30: required from ‘_FIter std::remove(_FIter, _FIter, const _Tp&) [with _FIter = __gnu_cxx::__normal_iterator<Types::segment*, std::vector<Types::segment> >; _Tp = Types::segment]’ /home/turgut/Desktop/CppProjects/videoo-render/src/utils/array_man.h:49:34: required from ‘void Utils::remove_element(std::vector<T>*, seek) [with vector_type = Types::segment; seek = Types::segment]’ /home/turgut/Desktop/CppProjects/videoo-render/src/Application.cpp:184:59: required from here /usr/include/c++/11/bits/predefined_ops.h:270:24: error: no match for ‘operator==’ (operand types are ‘Types::segment’ and ‘const Types::segment’) 270 | { return *__it == _M_value; }
我的模板函数实现
template<typename vector_type, typename seek> void remove_element(std::vector<vector_type>* vector, seek obj) { vector->erase(std::remove(vector->begin(), vector->end(), (seek)obj), vector->end()); }
调用代码
for(auto segment: opengl_engine->_textures){ if(must_delete){ Utils::remove_element<Types::segment, Types::segment>(&(opengl_engine->_textures), segment); } }
解决方案
1. 核心问题:缺少operator==重载
编译错误的直接原因是std::remove需要通过operator==比较Types::segment对象是否相等,但你的Types::segment类没有定义这个运算符。
给Types::segment添加operator==重载即可解决,示例如下:
namespace Types { class segment { // 你的类成员 public: // 成员函数形式重载 bool operator==(const segment& other) const { // 根据类逻辑实现相等判断,比如比较所有成员变量 return /* 你的相等条件 */; } }; // 或者全局函数形式(如果成员函数不合适) bool operator==(const segment& lhs, const segment& rhs) { return /* 你的相等条件 */; } }
2. 优化模板函数与调用逻辑
- 模板函数不需要两个模板参数,
seek类型可自动推导,简化为:
template<typename T> void remove_element(std::vector<T>& vec, const T& obj) { vec.erase(std::remove(vec.begin(), vec.end(), obj), vec.end()); }
调用时简化为:
Utils::remove_element(opengl_engine->_textures, segment);
- 注意:循环存在迭代器失效问题
用范围for循环遍历vector时删除元素,会导致迭代器失效,可能引发崩溃或跳过元素。正确做法是用迭代器遍历并删除:
auto& textures = opengl_engine->_textures; for(auto it = textures.begin(); it != textures.end(); ){ if(must_delete){ it = textures.erase(it); // erase返回下一个有效迭代器 } else { ++it; } }
3. 替代方案:用std::remove_if避免重载operator==
如果不想给Types::segment重载operator==,可以改用std::remove_if结合lambda表达式自定义比较逻辑:
template<typename T, typename Predicate> void remove_element_if(std::vector<T>& vec, Predicate pred) { vec.erase(std::remove_if(vec.begin(), vec.end(), pred), vec.end()); }
调用时传入判断逻辑:
Utils::remove_element_if(opengl_engine->_textures, [&segment](const Types::segment& s){ // 自定义相等判断逻辑,比如比较某个成员 return s.id == segment.id; });
内容的提问来源于stack exchange,提问作者Turgut
相关产品推荐
相关产品推荐

