Here's a simplified version of the code I'm using:
namespace BasketNovel {
void Engine::BuryEntities()
{
std::list<Entity*>::iterator iter = p_entities.begin();
while (iter != p_entities.end())
{
if ( (*iter)->getAlive() == false )
{
delete (*iter);
iter = p_entities.erase( iter ); //.erase returns next element
}
else iter++;
}
}
}
I'm getting the following warning from Intel Static Analysis:
BasketNovel.cpp(567): warning #12221: slicing of object "iter" passed as actual argument 2 in call to "std::_List_iterator > > std::list >::erase(std::_List_const_iterator > >)" occurs due to implicit type conversion
I believe that this is basically saying that I'm causing an implicit type conversion in:
iter = p_entities.erase( iter );
(note: I get the same warning even if I change my code to: p_entities.erase( iter++ ); )
I don't quite understand what I'm "slicing" in the above. What exactly does this mean and how I should go about solving this warning? I'd rather slightly convoluted code than turning off warning messages completely.
What is Object Slicing
Object Slicing is the fact of copying/moving only part of an object, this occurs in general with Base/Derived couples:
struct Base { int i; };
struct Derived: Base { int j; };
void slice() {
Derived d = {};
Base b(d); // b is a "sliced" version of `d`
}
and can lead to nastiness.
Here though, this is just a false positive...
Can it be easier ?
Yes, certainly.
// Place to be deleted values at the end
auto const it = std::partition(p_entities.begin(), p_entities.end(),
[](Entity const* e) { return not e or not e->getAlive(); });
// Delete them
std::for_each(it, p_entities.end(), [](Entity const* e) { delete e; });
// Remove them
p_entities.erase(it, p_entities.end());
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With