Jeremiah Willcock escribió:
On Mon, 10 May 2010, Richard Webb wrote:
Sounds like the same problem as https://svn.boost.org/trac/boost/ticket/3594
It seems like it is. Is the workaround that complicated, though? Is there a way to get some of that factored out to reuse in other Boost libraries? Would putting an explicit cast to ... std::pair::* in the template argument work instead?
Hi Jeremiah, The problem is not a bug with VC++ 10, but a collateral effect of the way std::pair is implemented in the stdlib provided for this compiler --namely, by deriving from an implementation-specific _Pair_base class where the members are actually defined. This reduced test case can help explain the problem: struct base{int x;}; struct derived:base{}; template< class Class, typename Type, Type Class::*PtrToMember
struct member{}; typedef member<derived,int,&derived::x> member_t; The last typedef fails with "argument of type 'int base::*' is incompatible with template parameter of type 'int derived::*'" or something to that effect because x is defined in base rather than derived, so the type of &derived::x is actually int base::*, for which the standard conversion to int derived::* does not apply in the context of template argument matching, see 14.3.2 [temp.arg.nontype] paragraph 5: "[...] for a nontype template-parameter of type pointer to object, qualification conversions (4.4) and the array-to-pointer conversion (4.2) are applied. [Note: In particular, neither the null pointer conversion (4.10) nor the derived-to-base conversion (4.10) are applied. [...] ]" I don't really know the rationale behind the paragraph above, but this is the way things are. The workaround applied at https://svn.boost.org/trac/boost/ticket/3594 works, but it's probably overkill (and uses the objectionable member_offset, which is really meant to be used as a last resort for legacy compilers). A nicer workaround consists in providing a user-defined key extractor: template<typename First,typename Second> class pair_first_extractor { typedef std::pair<First,Second> value_type; public: typedef First result_type; const result_type& operator()(const value_type& x)const { return x.first; } result_type& operator()(value_type& x)const { return x.first; } }; typedef multi_index::multi_index_container< std::pair<key_type, value_type>, multi_index::indexed_by< multi_index::sequenced<>, multi_index::hashed_unique< pair_first_extractor<key_type, value_type> >
ghost_cells_type;
HTH, Joaquín M López Muñoz Telefónica, Investigación y Desarrollo