With smart pointers there is no special issue, we barely use the erase-remove idiom as we already know it.
But there is some interest in this post, because we are about to use a lambda function and improve again our simple dump function, to let it deal with pointers.
Firstly, we write a class that we are about to use dinamically:
class Simple
{
private:
const int value_;
bool valid_;
public:
Simple(int value) : value_(value), valid_(true) {}
bool isValid() const { return valid_; }
void setValid(bool valid) { valid_ = valid; } const
int getValue() const { return value_; }
};
Then we write a variation on our function for dumping elements in a container, specific for pointers management:
template <typename T, typename InputIterator>
void dumpPtr(InputIterator begin, InputIterator end,
std::ostream& os = std::cout, const char* const delimiter = " ")
{
std::for_each(begin, end, [&] (T t) { os << *t << delimiter; } );
os << std::endl;
}
It doesn't change much, actually, from the previous version. We just acknowledge that we have to do with a pointer, and dereference it on usage.
We should remember to write an overload for the "put to" operator, so that we can output Simple objects:
std::ostream& operator<<(std::ostream& os, const Simple& s)
{
return os << s.getValue() << " (" << s.isValid() << ')';
}
We are going to work with shared pointers to Simple objects. A typedef is going to be useful:
typedef std::shared_ptr<Simple> SPS;Given all this, we create a vector of smart pointers to Simple, put some data in it, and mark as not valid a few items:
std::vector<SPS> vss;
vss.reserve(10);
for(int i = 0; i < 10; ++i)
vss.push_back(SPS(new Simple(i)));
vss[2]->setValid(false);
vss[5]->setValid(false);
vss[8]->setValid(false);
dumpPtr<SPS>(vss.begin(), vss.end());
And now the fun stuff:
vss.erase(std::remove_if(vss.begin(), vss.end(),
[] (SPS s) -> bool { return s->isValid() == false; }), vss.end());
It is just a line of code, but it is quite dense.
We use the remove_if() standard algorithm using as a predicate a lambda function (notice the "arrow" notation to specify its return type) that works on each smart pointer in the passed range. The returned iterator from remove_if() is used as beginning of the sequence that has to be erased from the vector.
More info on this issue in Item 33 of Effective STL, one of the Effective C++ book series by Scott Meyers.
No comments:
Post a Comment