C++ 向量按值删除会发出错误

C++ vector remove by value gives off an error

提问人:Turgut 提问时间:8/23/2022 更新时间:8/23/2022 访问量:103

问:

我遵循另一个问题来创建一个模板函数,该函数按值从向量中删除成员,但是当我尝试编译它时,我收到此错误:

/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);
  }
}
C++ 矢量 标准

评论

4赞 sweenish 8/23/2022
operand types are ‘Types::segment’ and ‘const Types::segment’您有一个类型不匹配。
6赞 perivesta 8/23/2022
看起来没有正确的.可能那个参数不是Types::segmentoperator==const
1赞 sweenish 8/23/2022
拥有两个模板参数感觉是多余的。至少总的来说,我没有看到它的必要性。
2赞 sweenish 8/23/2022
@NateEldredge 擦除/删除成语是众所周知的,甚至在 cpp偏好上推荐。 不受影响。vector->end()std::remove()
1赞 Nate Eldredge 8/23/2022
@sweenish:哦,我明白了,保持了大小,但最后的元素充满了垃圾。然后清理。std::removevector->erase

答:

2赞 sweenish 8/23/2022 #1

这里有一个玩具示例,可以完成您正在尝试做的事情。

#include <iostream>
#include <list>
#include <vector>

template <typename Container>
void remove_all_by_value(Container& c, typename Container::value_type val) {
  c.erase(std::remove_if(c.begin(), c.end(),
                         [&val](const auto& a) { return a == val; }),
          c.end());
}

template <typename Container>
void print_container(const Container& c) {
  for (const auto& i : c) {
    std::cout << i << ' ';
  }
  std::cout << '\n';
}

int main() {
  std::vector<int> one{1, 2, 3, 2, 4, 2, 5};
  print_container(one);
  remove_all_by_value(one, 2);
  print_container(one);

  std::cout << '\n';

  std::list<int> two{1, 2, 3, 2, 4, 2, 5};
  print_container(two);
  remove_all_by_value(two, 2);
  print_container(two);
}

std::remove_if 将删除与提供的 lambda 中条件匹配的所有对象。这完全消除了循环的需要。

我还没有费心安装 C++20 编译器,所以很可能存在一个利用概念和范围的更优雅的版本。