Boost logo

Boost Users :

From: JOAQUIN LOPEZ MU?Z (joaquin_at_[hidden])
Date: 2007-09-15 06:12:08


Hello,

----- Mensaje original -----
De: "T. Allison" <tallison_at_[hidden]>
Fecha: Sábado, Septiembre 15, 2007 6:28 am
Asunto: [Boost-users] Newbie MultiIndex shared_ptr non-trivial class
question
Para: boost-users_at_[hidden]

>
> I am attempting to use the Boost libraries for my first time. I
> am trying to create a MultiIndex container of shared_ptrs to
> fairly complicated objects. I've spent several days trying to
> figure this out, and I'm just spinning my wheels, and I'd really
> appreciate some help.

Regain your hope, we're going to make this work :) The problem
is due to some confusions between value_type's and key_type's.

> I'm afraid this message is somewhat lengthy as I''ve tried to
> include appropriate detail.
>
> I have a class of observations which I wish to sort by 9 elements.
> I have overloaded operator< for this class, like so:
> class Observation
> {
> [...]
> //Overloaded operator<, == etc.
> bool operator<(const Observation &rhs);

There's an error here (though it's not the primary error,
and it might be the case you've got it right in your original
code): operator< should be const.

> The code will dynamically create thousands of these things to be
> used in many ways, so I've opted to use shared_ptr:
> typedef boost::shared_ptr<Observation> SharedObservation;
> [...] If I write:
> typedef boost::multi_index_container<SharedObservation>
> ObservationCollection;

This is probably not what you meant: multi_index_container<T>
resolves to multi_index_container<T,indexed_by<
ordered_unique<identity<T> > > >, so the keys of
ObservationCollection are the SharedObservation objects
themselves, which is the Observation objects' *addresses*
as it can be deduced from the definition of shared_ptr
operator<.

[...]
> If I write:
> typedef boost::multi_index_container<SharedObservation>
> ObservationCollection;
> and
> void AnotherClass::functionUsingCollection(data)
> {
> SharedObservation temp(new Observation(data) );
> //Check and see if I've got one already, before I do anything
> master_collection.find(temp); //master collection is an object
> //of type ObservationCollection
> }

This is consistent with the definition of ObservationCollection
above but probably does not behave as intended:
master_collection.find(temp) depends on the address of the
object pointed to by temp rather than the contents (data).

> However, there is no point to using multi_index_container if I
> sort by only one index, so I've tried to expand out the index
> explicitly with an eye towards adding more indexes as I develop
> the code, like so:
> typedef boost::multi_index_container<
> SharedObservation,
> indexed_by<
> ordered_unique<identity<Observation> >
> >
> > ObservationCollection; //Add more indexing criteria later

OK. This is not the actual expansion of the former
ObservationCollection definition, since now you're using
identity<Observation> as the key extractor where you formerly had
the implicit identity<SharedObservation>. I understand this
latter definition is the one you really meant for. The problem is
that when you write

  master_collection.find(temp);

in functionUsingCollection, you're passing a SharedObservation
object where a *key* value is expected, that is, an Observation
object proper. Change the code to
  
void AnotherClass::functionUsingCollection(data)
{
   master_collection.find(Observation(data));
   ...

and be done (hopefully). Hope this helps. Please report back.

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


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