Boost logo

Boost :

From: Daryle Walker (dwalker07_at_[hidden])
Date: 2003-07-13 00:19:46


In another thread, by Joaquín M López Muñoz, there is talk of a helper
class like:

//================================================================
template<
   class Class,typename Type,
   Type Class::*PtrToMember,
   typename Compare=std::less<Type> >
struct less_by
{
   less_by(const Compare& comp=Compare()):comp(comp){}

   bool operator()(const Class& x,const Class& y)const
   {
     return comp(x.*PtrToMember,y.*PtrToMember);
   }

   bool operator()(const Type& x,const Class& y)const
   {
     return comp(x,y.*PtrToMember);
   }

   bool operator()(const Class& x,const Type& y)const
   {
     return comp(x.*PtrToMember,y);
   }

private:
   Compare comp;
};
//================================================================

[That was cut from the "multindex" trial code.] The author later
decided to segregate the extraction from the comparison. No code has
been given yet, but that class could be like:

//================================================================
template<
   class Class,typename Type,
   Type Class::*PtrToMember >
struct member
{
     Type const & operator ()( Class const &c ) const
         { return c.*PtrToMember; }

     Type & operator ()( Class &c ) const
         { return c.*PtrToMember; }
};
//================================================================

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; }
};
//================================================================

Or we can simplify the type extraction, at the cost/gain of needing to
specify the exact member at construction time by:

//================================================================
template < class Class, typename Type >
class member_extractor
{
public:
   typedef Class argument_type;
   typedef Type return_type;

   typedef Type Class::* member_type;

   explicit member_extractor( member_type m )
     : member_( m ) {}

   return_type const & operator ()( argument_type const &c ) const
     { return c.*member_; }

   return_type & operator ()( argument_type &c ) const
     { return c.*member_; }

   member_type get_member() const
     { return this->member_; }

private:
   member_type member_;
};
//================================================================

Daryle


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