What concepts/interface must the element type of multi_index_container<> support?
I'm trying to use boost::multi_index_container on a type that I've defined. I want the container to have two indices: 1. insertion order 2. hashed_unique Further, I want the hash to use an sha1 hash value, which I have represented as a struct. So, I have something like the following: struct sha1_hash_value { ... }; class MyRecord { public: ... sha1_hash_value hash() const { return _sha1_hash; } ... private: sha1_hash_value _sha1_hash; }; using namespace boost::multi_index; typedef boost::multi_index_container< MyRecord, indexed_by< sequenced<>, hashed_unique<const_mem_fun<MyRecord,sha1_hash_value,&MyRecord::hash> >
RecordSet;
When I compile this, I get lots of complaints regarding the conversions to/from the 'sha1_hash_value' type. I understand that I need to define appropriate member functions or specializations for this type. What I would like to know is what those member functions/specializations are and where that is documented so that I don't have to decipher compiler error gibberish iteratively and just cross my fingers that the errors are really about missing functionality and not about misuse. FWIW, if I change sha1_hash_value to a 'long', the code compiles, so it doesn't appear as if I'm completely misusing multi_index_container<>, though I'm certainly still open to that possibility as well. Thanks for any help. The brick wall I'm banging my head against is really starting to hurt.
El 16/09/2011 19:15, Chris Cleeland escribió:
I'm trying to use boost::multi_index_container on a type that I've defined. I want the container to have two indices:
1. insertion order 2. hashed_unique
Further, I want the hash to use an sha1 hash value, which I have represented as a struct. So, I have something like the following:
struct sha1_hash_value { ... };
class MyRecord { public: ... sha1_hash_value hash() const { return _sha1_hash; } ... private: sha1_hash_value _sha1_hash; };
using namespace boost::multi_index;
typedef boost::multi_index_container< MyRecord, indexed_by< sequenced<>, hashed_unique<const_mem_fun<MyRecord,sha1_hash_value,&MyRecord::hash> >
RecordSet;
Hi Chris, you have the concepts here slightly mixed up. The specification of a unique hashed index goes like (http://tinyurl.com/3n67upt ) hashed_unique< KeyFromValue, Hash=boost::hash<KeyFromValue::result_type>, Pred=std::equal_to<KeyFromValue::result_type>
where KeyFromValue is a key extractor, that is, the functor returning the piece of info on which you want to do the hashing, and Hash and Pred are the (hashing, equality) pair on that key. Furthermore, Hash must return a std::size_t. Your particular case is a little exotic because MyRecord stores a precalculated hash value (usually, the hash is calculated on the fly.) You can handle this situation in one of the following two ways: 1. Consider that the key is MyRecord::hash(): hashed_unique< const_mem_fun<MyRecord,sha1_hash_value,&MyRecord::hash>
For this to work, the default Hash predicate (boost::hash<sha1_hash_value>) has to be defined (hence your compiling problems), see http://tinyurl.com/5sfsmyo for details, and the same goes for std::equal<sha1_hash_value>. Alternatively you can provide your own Hash and Pred functors other than the default. As the sha1_hash_value is already a hash value, probably you only need to implement a conversion from sha1_hash_value to std::size_t. 2. Consider that the key is MyRecord hashed_unique< MyRecord
Here, the default value for Hash is boost::hash<MyRecord>, which again you must customize as explained in http://tinyurl.com/5sfsmyo , simply using the value returned by MyRecord::hash in the process. Similar considerations apply to std::equal<MyRercord>. Hope this helps, Joaquín M López Muñoz Telefónica, Investigación y Desarrollo Este mensaje se dirige exclusivamente a su destinatario. Puede consultar nuestra política de envío y recepción de correo electrónico en el enlace situado más abajo. This message is intended exclusively for its addressee. We only send and receive email on the basis of the terms set out at. http://www.tid.es/ES/PAGINAS/disclaimer.aspx
Joaquin, Thank you very much for the very clear explanation. I sort of figured things out late Friday, but left the question "out there" in the hopes that I would get a more authoritative answer/explanation; my "solution", while it worked, felt clumsy, so I figured there had to be a better way that I was missing. I believe what I had missed understanding the first time through were the default values for Hash and Pred On Mon, Sep 19, 2011 at 1:06 AM, <joaquin@tid.es> wrote:
The specification of a unique hashed index goes like (http://tinyurl.com/3n67upt )
hashed_unique< KeyFromValue, Hash=boost::hash<KeyFromValue::result_type>, Pred=std::equal_to<KeyFromValue::result_type>
And *this* was a big thing that I missed:
Furthermore, Hash must return a std::size_t.
and the compiler's error messages were very misleading with respect to what was wrong. I will review what I hacked in and re-evaluate based on the knowledge from your reply. Cheers! -cj
participants (2)
-
Chris Cleeland
-
joaquin@tid.es