|
Boost Users : |
Subject: [Boost-users] [multiindex] custom key extractor problem
From: Stephan Menzel (stephan.menzel_at_[hidden])
Date: 2008-12-04 13:13:07
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. Please consider this:
class Host {
public:
Host(const boost::asio::ip::address &ip) : m_ip(ip) {};
const boost::asio::ip::address &ip(void) const throw () { return m_ip; };
private:
Host(void) {};
boost::asio::ip::address m_ip;
};
typedef boost::shared_ptr<Host> HostPtr;
struct lthost {
bool operator()(const HostPtr &h1, const HostPtr &h2) const {
return (h1->ip() < h2->ip());
}
};
struct giveip { // this is supposedly my key extractor
typedef boost::asio::ip::address result_type;
const result_type &operator()(const HostPtr &p) const {
return p->ip();
};
};
typedef boost::multi_index_container<
HostPtr,
boost::multi_index::indexed_by<
boost::multi_index::ordered_unique<giveip>,
boost::multi_index::random_access<>
>
> HostSet;
typedef HostSet::nth_index<0>::type HostSetOrderedIndex;
typedef HostSet::nth_index<1>::type HostSetRandomIndex;
Now inserting and accessing elements compiles fine, just when I try to erase something...
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
}
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? 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<>
>
>
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.
I'm quite puzzled how this is supposed to work.
Can you give me some hints??
Thanks a lot,
Stephan
PS:
I know, the use case is kinda weird. Basically, I want to be able to insert elements with the set logic, and only the IP shall count as identity. Access via random access index is necessary to do hashing in a stable deterministic way over the container.
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