Boost logo

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