Boost logo

Boost :

From: Joaquín Mª López Muñoz (joaquin_at_[hidden])
Date: 2003-07-14 12:18:41


John Torjo ha escrito:

> >
> >Subject: Re: [boost] About member extraction
> > From: Joaquín Mª López Muñoz <joaquin_at_[hidden]>
> > Date: Mon, 14 Jul 2003 14:24:37 +0200
> > To: Boost mailing list <boost_at_[hidden]>
> >
> >
> >
> >Daryle Walker ha escrito:
> >
> >> But doesn't the "PtrToMember" template parameter already imply the
> >> "Type" and "Class" parameters? So specifying all three would be
> >> redundant. Could we reduce it by:
> >>
> >> //================================================================
> >> template < typename PtrToMember >
> >> struct member_extractor
> >> {
> >> // Don't know if this is a real type-traits class
> >> BOOST_STATIC_ASSERT(is_pointer_data_member<PtrToMember>::value);
> >>
> >> // The extractor traits classes aren't real (yet, maybe)
> >> typedef get_class_type<PtrToMember> argument_type;
> >> typedef get_member_type<PtrToMember> return_type;
> >>
> >> return_type const & operator ()( argument_type const &c ) const
> >> { return c.*PtrToMember; }
> >>
> >> return_type & operator ()( argument_type &c ) const
> >> { return c.*PtrToMember; }
> >> };
> >
> >Of the approaches you propose, this is the one that I like best, but
> >I'm afraid it cannot be implemented: Note that PtrToMember is a
> >*type* (something like int A::*), not a pointer to member.
> >member_extractor would have to defined as
> >
> >template < typename PtrToMember, PtrToMember ptr >
> >struct member_extractor
> >
> >and used as
> >
> >member_extractor<int A::*,&A::x>; // x is an int member of A
>
> Actually, I think it's worse (I don't have a C++ compiler with me right now:-( )
>
> Something in the lines of:
>
> template < typename type, typename result, result type::* ptr >
> struct member_extractor
>
>

Actually, extracting "A" and "int" from "int A::*" is easy:

#include <boost/static_assert.hpp>
#include <boost/type_traits.hpp>

using namespace std;

struct A
{
  int x;
};

template <typename PtrToMember>
struct ptr_to_member_descriptor;

template <typename Class,typename Member>
struct ptr_to_member_descriptor<Member Class::*>
{
  typedef Class class_type;
  typedef Member member_type;
};

int main()
{
  BOOST_STATIC_ASSERT((
    boost::is_same<
      ptr_to_member_descriptor<int A::*>::class_type,
      A>::value));

  BOOST_STATIC_ASSERT((
    boost::is_same<
      ptr_to_member_descriptor<int A::*>::member_type,
      int>::value));

  return 0;
}

The really hard part is how to obtain "int A::*" from "&A::x". I don't
think this is possible, but then again people here sometimes do magic :)

Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk