On Fri, Dec 25, 2015 at 5:31 AM, Joaquin M Lopez Munoz <joaquin@tid.es> 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