c++boost-multi-index

boost_multi_index iterator dereference gives const


This is related to dereference boost_multi_index hashed_index iterator. Please see the code below:

using namespace boost;
using namespace boost::multi_index;
using Container = boost::multi_index_container<
    std::string,
    indexed_by<hashed_unique<const_mem_fun<std::string, size_t, &std::string::size>>>>;

Container container;
auto& hash_map = container.get<0>();
auto[it, inserted] = hash_map.insert("1234");
if (!inserted)
    *it = "1234";

Which gives:

error: no match for 'operator=' (operand types are 'const value_type {aka const std::__cxx11::basic_string<char>}' and 'const char [5]')
         *it = "1234";
               ^~~~~~

So, looks like it is possible to call only const methods on the object referenced by iterator it.

  1. Why is it done in this way? (Is it for container to be able to track all the changes?)
  2. Is there better/another way to write to the referenced object?

Solution

  • Boost.MultiIndex iterators are const (won't give you non-const access to the element) because otherwise values could be changed without the owning multi_index_container knowing, which would result in elements being mispositioned, undefined behavior, etc. This is the same situation as iterators in a std::set, for instance.

    To modify an element, there are various facilities discussed here. Note that the documentation is pre-C++11 and does not mention the use of lambda expressions in combination with modify, which would look like:

    hash_map.modify(it,[](std::string& x){x="1234";});