[MultiIndex] more on key extractor issues

I think my problem stems from the use of 'const' in the underlying element with pointer traversal. Consider: typedef multi_index_container< shared_ptr< const ItemBase >, indexed_by< ordered_non_unique< member< const ItemBase, // <<--- here const unsigned long, // <<--- here &ItemBase::some_member > >, // ordered_non_unique ordered_unique< tag<S2>, member< ItemBase, const S2, &ItemBase::another_member > > // ordered_unique > // indexed_by > ItemList_type_base; I added the two 'const' occurrences on the lines marked with "here", and it behaved better. I think it worked with the second index originally because one of those const's was originally there. The member in question was originally const, so I had included const as part of the type there. Basically, what is happening on Windows VS10 is: template<class Class,typename Type,Type Class::*PtrToMember> struct non_const_member_base { typedef Type result_type; template<typename ChainedPtr> #if !defined(BOOST_NO_SFINAE) typename disable_if< is_convertible<const ChainedPtr&,const Class&>,Type&>::type #else Type& #endif operator()(const ChainedPtr& x)const { return operator()(*x); // <<-- HERE } const Type& operator()(const Class& x,int=0)const { return x.*PtrToMember; } Type& operator()(Class& x)const { return x.*PtrToMember; } }; The ChainedPointer form unpeels a const-qualified type with (*x), and that matches the middle form, not the third. But the signature on the first form is looking for Type, which is exactly what I put in the member<...> index directive. So, I suggest that a quick note concerning constant types inside chained pointer following could be added to the tutorial section. Meanwhile, a stranger problem occured on the Mac, using the Clang compiler. I got an error saying that none of the operator() candidates were viable for overloading, with the error indicating that the type of thing being passed in was the shared_ptr<const ItemBase>. It said the first form was ignored because of instantiation failure, but that is exactly contrary to the disable_if. I'm suspecting that the is_convertable itself somehow choked rather than producing false_type...? Naturally none of the other overloads matched, as a shared_ptr<T> cannot be passed where a T is expected, and that's exactly when the first form would be switched in! —John

John M. Dlugosz <mpbecey7gu <at> snkmail.com> writes:
I think my problem stems from the use of 'const' in the underlying element with pointer traversal.
Consider:
typedef multi_index_container< shared_ptr< const ItemBase >, indexed_by<
ordered_non_unique< member< const ItemBase, // <<--- here const unsigned long, // <<--- here &ItemBase::some_member > >, // ordered_non_unique
ordered_unique< tag<S2>, member< ItemBase, const S2, &ItemBase::another_member > > // ordered_unique
> // indexed_by > ItemList_type_base;
Have you taken a look at the table in: http://www.boost.org/libs/multi_index/doc/tutorial/ key_extraction.html#advanced_key_extractors Regardless of whether the indexed-by member is const or not, when using pointers to const elements the proper way of declaring the extractors is: member< ItemBase, const unsigned long, &ItemBase::some_member
member< ItemBase, const S2, &ItemBase::another_member
This should clear problems away both in VS and Clang (please report otherwise.) Joaquín M López Muñoz Telefónica Digital
participants (2)
-
Joaquin M Lopez Munoz
-
John M. Dlugosz