Re: [boost] About member extraction
John Torjo ha escrito: > > > >Subject: Re: [boost] About member extraction > > From: Joaquín Mª López Muñoz <[EMAIL PROTECTED]> > > Date: Mon, 14 Jul 2003 14:24:37 +0200 > > To: Boost mailing list <[EMAIL PROTECTED]> > > > > > > > >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::value); > >> > >>// The extractor traits classes aren't real (yet, maybe) > >>typedef get_class_type argument_type; > >>typedef get_member_type 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; // 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 #include using namespace std; struct A { int x; }; template struct ptr_to_member_descriptor; template struct ptr_to_member_descriptor { typedef Class class_type; typedef Member member_type; }; int main() { BOOST_STATIC_ASSERT(( boost::is_same< ptr_to_member_descriptor::class_type, A>::value)); BOOST_STATIC_ASSERT(( boost::is_same< ptr_to_member_descriptor::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 ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] About member extraction
> >Subject: Re: [boost] About member extraction > From: Joaquín Mª López Muñoz <[EMAIL PROTECTED]> > Date: Mon, 14 Jul 2003 14:24:37 +0200 > To: Boost mailing list <[EMAIL PROTECTED]> > > > >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::value); >> >>// The extractor traits classes aren't real (yet, maybe) >>typedef get_class_type argument_type; >>typedef get_member_type 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; // 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 > >which takes us again to the redundancy we were trying to avoid. >Something in the way of eliminating this redundancy, however, would be >a boon. Maybe some metaprogramming gurus here can think of >something. > I would really love to see a solution to this ;-) Best, John >Joaquín M López Muñoz >Telefónica, Investigación y Desarrollo > >___ >Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] About member extraction
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::value); > >// The extractor traits classes aren't real (yet, maybe) >typedef get_class_type argument_type; >typedef get_member_type 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; // x is an int member of A which takes us again to the redundancy we were trying to avoid. Something in the way of eliminating this redundancy, however, would be a boon. Maybe some metaprogramming gurus here can think of something. Joaquín M López Muñoz Telefónica, Investigación y Desarrollo ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] About member extraction
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 > 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::value); // The extractor traits classes aren't real (yet, maybe) typedef get_class_type argument_type; typedef get_member_type 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 ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost