Boost logo

Boost Users :

Subject: Re: [Boost-users] [multiindex] custom key extractor problem
From: Joaquin M Lopez Munoz (joaquin_at_[hidden])
Date: 2008-12-04 15:18:36


Bugzilla from stephan.menzel_at_gmx.eu wrote:
>
> Hi everyone,
>
> I could need a little advice using boost multiindex as follows:
> I have a Host class and I want to store HostPtrs in a multiindex container
> to a) have a member ip() as a key to unique hosts and b) be able to access
> random hosts via operator[]. The problem as I understand is the
> shared_ptr.
> [...]
> int main(int argc, char **argv) {
>
> HostSet s;
>
> HostPtr p1(new
> Host(boost::asio::ip::address::from_string("127.0.0.1")));
> HostPtr p2(new
> Host(boost::asio::ip::address::from_string("10.10.55.1")));
>
> // now place a pointer to that host in the multiset.
> HostSetOrderedIndex &oi = s.get<0>();
> oi.insert(p1);
> oi.insert(p2);
>
> oi.erase(p1); // booom
> }
>

This can't possibly compile: erase() can accept either an iterator or a key,
and p1 is neither. You can write:

  oi.erase(p1->ip());

and everything compiles and works just fine. Your key for
HostSetOrderedIndex
is std::string, which is exactly what you want AFAICS.

> Basically, I want the index to access each ptr's ip() function to get the
> key rather than the ptr itself, which would be just random mem as far as I
> understand it. So the key extractor should work, shouldn't it?
>

Yes, this is what you currently have, HostPtrs are indexed by IP. And the
key extractor works, it's only the confusion about erase that I think is
misleading you.

> I also tried the lthost() function:
>
> typedef boost::multi_index_container<
> HostPtr,
> boost::multi_index::indexed_by<
>
> boost::multi_index::ordered_unique<boost::multi_index::identity<HostPtr>,
> lthost>,
> boost::multi_index::random_access<>
> >
>>
>

In this variation the key is HostPtr, which are sorted by their IPs.
Noy you could legitimately use oi.erase(p1), for instance, though the
former version is probably better because it allows you to lookup
passing only a string instead of a whole HostPtr, which is more expensive
to create.

> But that doesn't work either. I guess it's accessing the HostPtr directly
> instead of dereferencing it. It does compile and also does the job but
> tests have shown that when I do this:
>
> HostSetOrderedIndex &oi = s.get<0>();
> oi.insert(p2);
>
> HostSetRandomIndex &hsri = s.get<1>();
> hsri.sort();
>
> and then iterate over the container (hsri) the order will vary. Sometimes
> one of the hosts appears at [0] sometimes the other.
>

This is because hsri.sort() does the sorting based on std::less<HostPtr>,
which
is not what you want. Write this instead:

hsri.sort(lthost());

to explicitly specify that you want your elements sorted according
to lthost. Note that the fact that HostSetOrderedIndex uses lthost
does not affect in any manner the way HostSetRandomIndex operates.

HTH,

Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo

-- 
View this message in context: http://www.nabble.com/-multiindex--custom-key-extractor-problem-tp20839161p20841599.html
Sent from the Boost - Users mailing list archive at Nabble.com.

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