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 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
class pair_first_extractor
{
typedef std::pair 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,
multi_index::indexed_by<
multi_index::sequenced<>,
multi_index::hashed_unique<
pair_first_extractor
>
ghost_cells_type;
HTH,
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo