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.