Newbie MultiIndex shared_ptr non-trivial class question
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. 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 { private: int x1; int x2; double x3; ... double x9; //other elements public: //Get Methods int GetX1(); int GetX2(); double GetX3(); ... double GetX9; //Overloaded operator<, == etc. bool operator<(const Observation &rhs); //appropriate nontrivial logic } 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; I wish to view my collection of these various sorting criteria, or as linked lists, so I'm trying to use multi_index_container. 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 } 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
This does not compile on my Linux g++ (4. something bigger than 0) compiler. After a truly horrendous spewage, the crux of the messages seem to be lines like usr/include/boost/multi_index/detail/ord_index_ops.hpp:65: error: no match for call to ‘(const std::less<fuser::Observation>) (fuser::Observation&, const boost::shared_ptr<fuser::tr<fuser::Observation>&)' and /usr/include/boost/multi_index/detail/ord_index_ops.hpp:72: error: no match for call to ‘(const std::less<fuser::Observation>) (const boost::shared_ptr<fuser::Observation>&, fuserObservation>&)' usr/include/c++/4.1.2/bits/stl_function.h:226: note: candidates are: bool std::less<_Tp>::operator()(const _Tp&, const _Tp&) const [with _Tp = fuser::Observation] I tried adding a function less(shared_ptr &, Obervation &), but it didn't help. The command used to compile is g++ -Wno-deprecated -Wnon-non-template-friend -frepo -m32 Thanks, Getting Desperate T Allison -- View this message in context: http://www.nabble.com/Newbie-MultiIndex-shared_ptr-non-trivial-class-questio... Sent from the Boost - Users mailing list archive at Nabble.com.
Hello, ----- Mensaje original ----- De: "T. Allison" <tallison@meicompany.com> Fecha: Sábado, Septiembre 15, 2007 6:28 am Asunto: [Boost-users] Newbie MultiIndex shared_ptr non-trivial class question Para: boost-users@lists.boost.org
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
Joaquín Mª López Muñoz wrote:
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.
You're right - about the only thing I did correctly was make operator< const! Joaquín Mª López Muñoz wrote:
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: [...] 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
You were exactly right about my intent and the fix. The recommended fix works exactly as I intended. -- View this message in context: http://www.nabble.com/Newbie-MultiIndex-shared_ptr-non-trivial-class-questio... Sent from the Boost - Users mailing list archive at Nabble.com.
participants (2)
-
"JOAQUIN LOPEZ MU?Z"
-
T. Allison