Getting a non-constant iterator in a container with multiple Boost indices

Using Boost 1_33_1, I get an error message implying that my iterator is a constant iterator (because it will not allow me to get the result from find ()).

$ g++ bmi_iter_tst.cpp bmi_iter_tst.cpp: In function 'void tst(employee_set&)': bmi_iter_tst.cpp:32: error: invalid initialization of reference of type 'employee&' from expression of type 'const employee' 

I know that I should not change any of the key values, and I do not, but I still need the non-constant acces sto to change other data in the elements of the container.

I know that I did it successfully elsewhere, I just can't figure out what this constant would do.

The code below is derived from the source example boost::multi_index

 #include <boost/multi_index_container.hpp> #include <boost/multi_index/member.hpp> #include <boost/multi_index/ordered_index.hpp> using boost::multi_index_container; using namespace boost::multi_index; struct employee { int id; int tst; employee(int id_):id(id_), tst(0){} }; struct id{}; typedef multi_index_container< employee, indexed_by< ordered_unique< tag<id>, BOOST_MULTI_INDEX_MEMBER(employee,int,id)> > > employee_set; void tst(employee_set& s) { employee_set::index_iterator<id>::type it = s.get<id>().find(11); employee& eref = *it; eref.tst++; } 
+6
source share
3 answers

From MultiIndex documents to random access indices :

As usual in Boost.MultiIndex, the elements of random access indexes are immutable and can only be changed using member functions and modified. This eliminates the use of many mutating algorithms, which nevertheless apply to std :: vectors.

This also applies to ordered indexes .

+3
source

multi_index does not know that you are not going to change members that are key values. That is why it implements only const_iterator.

If you want to change the non-key, you can use the modify function. If you intend to change the key value, you can use the modify_key or replace member modify_key . You can get more information here .

+9
source

multi_index_container<T,...> iterators are immutable regardless of whether typename T a class type ( U ) or a pointer type ( U* ). The drafters decided to impose this restriction in order to protect and emphasize the fact that changing the element directly (that is, through an iterator) can violate the integrity constraints of any key-based (associative) container indices.

For example: The ordered_unique index will be completely invalidated if a direct modification of an element (via an iterator) causes the index to no longer be ordered or unique , and multi_index_container itself multi_index_container not know about this change / invalidity (and would not program).

Here is the verbatim explanation provided by the companions:

By design, index elements are immutable, i.e. iterators only provide const access to them and only through the provided update interface (replace, modify and modify_key) can be changed. This restriction is set so that the internal invariants of key indexes are not violated (for example, ascending ascending into ordered indexes), but causes important restrictions in non-key indexes:

Error correction

Of course, there are always ways around const-correctness, the most obvious way is const_cast ... but the spirit of C ++ is that the programmer should be allowed to do whatever he or she wants, even if it is potentially dangerous. The developers of C ++ C ++ simply do their best to discourage this use. And, I hope, when programmers decide to circumvent these guarantees, this is because they have good reasons and they know exactly what they are doing.

Hope this helps.

+3
source

Source: https://habr.com/ru/post/900156/


All Articles