Boost logo

Boost Users :

Subject: Re: [Boost-users] [multi_index] do erase() call key extractors?
From: Nick Stokes (randomaccessiterator_at_[hidden])
Date: 2015-12-25 13:18:47


On Fri, Dec 25, 2015 at 5:31 AM, Joaquin M Lopez Munoz <joaquin_at_[hidden]>
wrote:

> Nick Stokes <randomaccessiterator <at> gmail.com> writes:
>
> >
> > This is probably rather obvious, but I wasn't able to locate this
> > guarantee in MIC docs. Take,
> >
> > struct Foo {
> > explicit Foo(Bar* b = nullptr) : bar(b) {}
> > Bar* bar;
> > };
> >
> > int getBarValue (const Foo& f) {
> > assert( f.bar );
> > return f.bar->getValue();
> > }
> >
> >
> > boost::multi_index< Foo, indexed_by<
> > hashed_unique < member<Foo, Bar* , &Foo::bar > >>
> > , hashed_non_unique < global_fun<const Foo&, int, &getBarValue >>
> > >> FooIndex;
> >
> > void grill() {
> > FooIndex fooIndex;
> >
> > Bar* b;
> > {
> > auto bWork = make_unique<Bar>();
> > // ...
> > fooIndex.emplace( bWork.get() );
> > b = bWork.get();
> > }
> >
> > fooIndex.erase(b);
> >
> > // ...
> > }
> >
> >
> > Please ignore the fact that raw-pointers are potentially dangerous etc.
> > The question is does erase() call getBarValue() despite the fact
> > I am using the first index?
>
> No. No key extractor or any other user-provided functor (compare
> predicate, hash function etc.) is ever used when erasing an element by
> iterator, regardless of the index you're using to do it. If you
> take a look at the docs for erase(iterator) at
>
> http://www.boost.org/libs/multi_index/doc/
> reference/hash_indices.html#modifiers
>
> you'll see the exception safery if guaranteedly "nothrow", which
> means erase can't invoke any possibily-throwing user-provided function.
> This applies to all indices of Boost.MultiIndex.
> erase(const key_type&), on the other hand, needs to determine the
> elements to be erased by key extraction, hashing and comparing for
> equality (in the case of hashed indices) or key extraction [...]

Thank you very much Joaquín. With your explanation clarifying the nothrow,
the docs are very clear indeed.

I guess my question is a little more subtle. I think I understand now, but
please let me reaffirm: In my example, erase(const key_type&) is being
called for the 1-st index (key_type is Bar*), which
*could* potentially throw, but in this case this is a simple pointer value
and hashing and equality and therefore do *not* throw. But to adjust the
2nd index, MIC does not require the key_extraction on that (which would
throw, or in fact, segv), because the node is already identified and is
erased. Is that correct?

Thanks,
Nick



Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net