How do I update overlapping indexes in a boost::multi_index_container?

断了今生、忘了曾经 提交于 2019-12-11 11:40:33

问题


I'm using boost 1.48.0, and I don't have the option to upgrade.

I've built a multi_index_container with indexes that have overlapping criteria. How are indexes sharing the same indexing criteria effected, as in the following example? The last line of the example code alludes to what I am asking for.

struct street_address_key : composite_key<
    t_postal_address
    , const_mem_fun<const_mem_fun<t_postal_address, string, &t_postal_address::street_name>>
    , const_mem_fun<const_mem_fun<t_postal_address, long, &t_postal_address::house_number>>
    , const_mem_fun<const_mem_fun<t_postal_address, string, &t_postal_address::city>>
    , const_mem_fun<const_mem_fun<t_postal_address, string, &t_postal_address::state>>
    , const_mem_fun<const_mem_fun<t_postal_address, long, &t_postal_address::zip_code>>
> {};

multi_index<
    t_postal_address
    indexed_by<
        ordered_unique<street_address_key>
        , ordered_non_unique<const_mem_fun<t_postal_address, string, &t_postal_address::name>>
        , ordered_non_unique<const_mem_fun<const_mem_fun<t_postal_address, string, &t_postal_address::street_name>>
        , ordered_non_unique<const_mem_fun<const_mem_fun<t_postal_address, long, &t_postal_address::house_number>>
        , ordered_non_unique<const_mem_fun<const_mem_fun<t_postal_address, string, &t_postal_address::city>>
        , ordered_non_unique<const_mem_fun<const_mem_fun<t_postal_address, string, &t_postal_address::state>>
        , ordered_non_unique<const_mem_fun<const_mem_fun<t_postal_address, long, &t_postal_address::zip_code>>
    >
> t_address_book;

...

t_address_book::nth_element<0>::type::iterator address_iter = book.find(some_address_tuple);

book.modify(address_iter, modify_city_method);

auto city_range = book.get<4>().equal_range( \*???*\ );

The city index shares the same criteria as the street_address_key. Modifying via the street_address_key, as I understand it, would ensure the index is appropriately updated. But what is the state of the "city" index? Was it updated to reflect the change in city name? Or is it in a broken state? Could I still locate the same address index with the old city? Do I have to update this index separately? Could I call a no-op Modifier to update the index?

// Presume I have the city element from the index.
// Is this supposed to update the city index after it was modified above?

book.get<4>().modify(city_iter, [](t_postal_address &) {});

回答1:


It looks to me like there should be no problem:

The documentation mentions:

Effects: Calls mod(e) where e is the element pointed to by position and rearranges *position into all the indices of the multi_index_container. Rearrangement is successful if

  • the index is non-unique OR no other element exists with equivalent key,
  • AND rearrangement is allowed by all other indices of the multi_index_container. If the rearrangement fails, the element is erased.

This implies all indexes are updated. Note that all indexes can in principle reject the edit. You may want to use a rollback to protect against loss of data.




回答2:


As @sehe comments, indices are all updated so you're safe. Additional observation: your index #2

ordered_non_unique<const_mem_fun<const_mem_fun<t_postal_address, string, &t_postal_address::street_name>>

is actually redundant with index #0 (the one based on a composite key): you can pass just a string (representing a street name) to index #0 and it'll behave exactly as index #2. This saves you some space and execution time. The magic behind it lies in the fact that when using composite keys you're allowed to pass partial information, down to just the first element of the composite key.



来源:https://stackoverflow.com/questions/23070473/how-do-i-update-overlapping-indexes-in-a-boostmulti-index-container

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!