if I uncomment these
//BaseList baselist;
//MemberList memberlist;
outside the loop and comment out the ones inside the loop it
I've seen it late, but anyways, here goes:
What you describe matches exactly the implementation of an intrusive hash table of MyClass elements, where
anInt1 is the hash (the bucket identifier) for an elementequality is defined as equality of (anInt1, Name)
So really, your program could just be:
Live On Coliru
std::unordered_set values {
{ "John", 0 }, { "Mike", 1 }, { "Dagobart", 2 },
{ "John", 3 }, { "Mike", 4 }, { "Dagobart", 5 },
{ "John", 6 }, { "Mike", 7 }, { "Dagobart", 8 },
{ "John", 9 }, { "Mike", 10 },
};
for(int i = 0; i<=3; ++i) {
if(2 == i) {
for(auto& e: values) std::cout << e.name << " "; std::cout << "\n";
for(auto& e: values) e.bIsMarkedToDelete |= ("Mike" == e.name);
for(auto it=begin(values); it!=end(values);) {
if (it->bIsMarkedToDelete) it = values.erase(it);
else ++it;
}
}
std::cout << "i=" << i << ", values.size(): " << values.size() << "\n";
}
values.clear();
std::cout << "Done\n";
if you really wanted contiguous storage, I can only assume you wanted this for performance
you do not want to use pointers instead of objects, since that simply negates the memory layout ("AllThingsBunchedTogether") benefits and you'd be better of with the unordered_set or unodered_map as above
you do not want to use auto_unlink mode, since it cripples performance (by doing uncontrolled deletion triggers, by inhibiting constant-time size() and by creating thread safety issues)
instead, you should employ the above stratagy, but with boost::intrusive::unordered_set instead see http://www.boost.org/doc/libs/1_57_0/doc/html/intrusive/unordered_set_unordered_multiset.html
Here, again, is a proof-of-concept:
Live On Coliru
#include
#include
#include
#include
//#include
//#include
namespace bic = boost::intrusive;
struct MyClass : bic::unordered_set_base_hook>
{
std::string name;
int anInt1;
mutable bool bIsMarkedToDelete;
MyClass(std::string name, int i) : name(name), anInt1(i), bIsMarkedToDelete(false) {}
bool operator==(MyClass const& o) const { return anInt1 == o.anInt1 && name == o.name; }
struct hasher { size_t operator()(MyClass const& o) const { return o.anInt1; } };
};
typedef bic::unordered_set, bic::constant_time_size > HashTable;
int main() {
std::vector values {
MyClass { "John", 0 }, MyClass { "Mike", 1 }, MyClass { "Dagobart", 2 },
MyClass { "John", 3 }, MyClass { "Mike", 4 }, MyClass { "Dagobart", 5 },
MyClass { "John", 6 }, MyClass { "Mike", 7 }, MyClass { "Dagobart", 8 },
MyClass { "John", 9 }, MyClass { "Mike", 10 },
};
HashTable::bucket_type buckets[100];
HashTable hashtable(values.begin(), values.end(), HashTable::bucket_traits(buckets, 100));
for(int i = 0; i<=3; ++i) {
if(2 == i) {
for(auto& e: values) std::cout << e.name << " "; std::cout << "\n";
for(auto& e: values) e.bIsMarkedToDelete |= ("Mike" == e.name);
values.erase(std::remove_if(begin(values), end(values), std::mem_fn(&MyClass::bIsMarkedToDelete)));
}
std::cout << "i=" << i << ", values.size(): " << values.size() << "\n";
std::cout << "i=" << i << ", hashtable.size(): " << hashtable.size() << "\n";
}
values.clear();
std::cout << "Done\n";
}