C++ Marking objects for removal in STD list via nullptrs -


i wondering if accaptable practice:

struct item { }; std::list<std::shared_ptr<item>> items; std::list<std::shared_ptr<item>> removeditems;  void update() {     items.push_back(std::make_shared<item>()); // sample item      (auto itemiterator=items.begin();itemiterator!=items.end();itemiterator++)     {         if (true) { // complex condition, (true) demo purposes             removeditems.push_back(std::move(*itemiterator)); // move ownership             *itemiterator=nullptr; // set current item nullptr         }          // 1 of downsides, have check if         // current iterator value not nullptr         if (*itemiterator!=nullptr) {             // complex loop items collection modified         }     }      // after loop done, can safely remove our objects      removeditems.clear(); // calls destructors on objects      //finally clear items nullptr     items.erase( std::remove_if( items.begin(), items.end(),         [](const std::shared_ptr<item>& itemtocheck){             return itemtocheck==nullptr;     }), items.end() ); } 

the idea here we're marking items container effected outside sources. when item removed container, it's set nullptr moved removeditems before that.

something event might effect items , add/remove items, had come solution.

does seem idea?

i think complicating things much. if in multi-threaded situation (you didn't mention in question), need locks guarding reads other threads access modified lists. since there no concurrent data structures in standard library, need add such stuff yourself.

for single-threaded code, can call std:list member remove_if predicate. there no need set pointers null, store them , multiple passes on data.

#include <algorithm> #include <list> #include <memory> #include <iostream>  using item = int;  int main() {     auto lst = std::list< std::shared_ptr<item> >      {          std::make_shared<int>(0),          std::make_shared<int>(1),          std::make_shared<int>(2),          std::make_shared<int>(3),              };          // shared_ptrs elements     auto x0 = *std::next(begin(lst), 0);     auto x2 = *std::next(begin(lst), 2);      // erase numbers     lst.remove_if([](std::shared_ptr<int> p){         return *p % 2 == 0;         });      // numbers have been erased     (auto = begin(lst); != end(lst); ++it)         std::cout << **it << ",";         std::cout << "\n";      // shared pointers members still valid     std::cout << *x0 << "," << *x2; } 

live example.

note elements have been erased list, not put @ end of list. latter effect standard algorithm std::remove_if do, , after have call std::list member function erase. two-step erase-remove idiom looks this

// move numbers end of list in unspecified state auto res = std::remove_if(begin(lst), end(lst), [](std::shared_ptr<int> p){     return *p % 2 == 0;     });  // erase numbers lst.erase(res, end(lst)); 

live example.

however, in both cases, underlying item elements have not been deleted, since each still have shared pointer associated them. if refence counts drop zero, former list elements deleted.


Comments

Popular posts from this blog

java.util.scanner - How to read and add only numbers to array from a text file -

rewrite - Trouble with Wordpress multiple custom querystrings -