I have a situation similar to the one described in this thread: Getting around Boost Multi-Index container's constant elemets. In short, I have a boost multi index container holding a struct like this:
struct Data {
Controller controller;
const int indexed_data;
}
My indexed data never changes, but the controller does. So, my first approach was to do all I need in a modify call:
container.modify(it, [](auto& data) {
data.controller.nonConstFunction();
});
Apparently this works for me, but I was performing some tests to understand the behaviour of this method when an exception is thrown inside the lambda (which will happen in my case), and I was surprised with the result:
struct employee {
int id;
std::string name;
}
typedef multi_index_container<
employee,
indexed_by<
ordered_unique<BOOST_MULTI_INDEX_MEMBER(employee,int,id)>>
>
> employee_set;
employee_set es;
es.insert(employee{0,"Joe"});
es.insert(employee{1,"Carl"});
es.insert(employee{2,"Robert"});
es.insert(employee{4,"John"});
try {
auto it = es.find(4); // John
es.modify(it, [](auto& employee) {
employee.id = 1; // Same ID of Carl, should be erased
throw std::runtime_error("test");
});
} catch (const std::runtime_error& err) {
// handle error...
}
After this, if you print the contents of the container you get:
0 Joe
1 Carl
2 Robert
1 John
Although without throwing the exception and only changing the employee's ID to one already existent, the hit on the index is detected and the employee being modified is erased.
Like I said, I don't perform any changes to my container's keys, but after finding out about this I am concerned. Is this a bug on the library? Are there any other situations that can lead to an invalid state of the indexes? I also couldn't find a way to "reprocess" the indexes to a valid state besides manually deleting/modifying one of the "invalid" entries.
Apart from that (and going back to my own case), is using modify the best approach to actually call methods on my controller, or should I follow the advise of the thread beforementioned and declare my controller mutable
? The latter looks quite dangerous for me because one could easily mess around with the index by declaring anything mutable
, but as I just showed, the safe way of doing it has just proved to be not so safe after all.