|
Boost Users : |
Subject: Re: [Boost-users] [MultiIndex] Visual C++ 10 issue
From: joaquin_at_[hidden]
Date: 2010-05-11 02:23:35
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
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