Home > front end >  C vector remove by value gives off an error
C vector remove by value gives off an error

Time:08-24

I've followed another question to create a template function that removes a member from a vector by value, however when I try to compile it I'm getting this error:

/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; }

Here is what my function looks like:

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());
    }

And here is how I use it:

for(auto segment: opengl_engine->_textures){
  if(must_delete){
    Utils::remove_element<Types::segment, Types::segment>(&(opengl_engine->_textures), 
    segment);
  }
}

CodePudding user response:

Here is a toy example that does what you're trying to do.

#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 will remove all objects that match the criteria in the provided lambda. This removes the need to have a loop at all.

I haven't been bothered to install a C 20 compiler yet, so it's very likely that there exists a more elegant version that utilizes concepts and ranges.

  • Related