Quote:Original post by snk_kid
Quote:Original post by Andrew Russell
Quote:Original post by Shannon Barber
PS I'm pretty sure you can overload the comma operator.
You can *evil grin*.
And boost assignment library uses it [wink]. Did you know ->* (not * or ->) is overloadable [grin] i'm serious! its called member pointer operator
Not only did I know that, but I have indeed overloaded it. You see, I wanted to be able to use mem_fun_ptr with more than just raw pointers, so I created my own almost an exact clone (I think) of std::mem_fun_ptr that instead returned a structure who's operator() took a template parameter, rather than simply a raw pointer (although one could be provided as the template parameter) like so:
template < typename pointer_type >result_type operator()( pointer_type pointer ) const { return (pointer->*function)();}
Of course, the pointer class in question must overload operator->*, which I found out was extremely nasty. Here's just for allowing ->* to work with zero and one argument functions, out of my cloning_ptr class:
//operator->* for pointer-to-member-0-argument-functiontemplate < typename result_type >boost::function< result_type ( void ) > operator->*( result_type (value_type::*function)( void ) ) { return boost::bind( function , pointer );}template < typename result_type >boost::function< result_type ( void ) > operator->*( result_type (value_type::*function)( void ) const ) const { return boost::bind( function , pointer );} //operator->* for pointer-to-member-1-argument-functiontemplate < typename result_type , typename argument_type >boost::function< result_type ( argument_type ) > operator->*( result_type (value_type::*function)( argument_type ) ) { return boost::bind( function , pointer );}template < typename result_type , typename argument_type >boost::function< result_type ( argument_type ) > operator->*( result_type (value_type::*function)( argument_type ) const ) const { return boost::bind( function , pointer );}
Zahlman: I figured out how to get operator+= working with the left argument remaining a reference - you provide two functions:
template <typename car_t, typename cdar_t, typename cddr_t>const conslist< car_t , conslist<cdar_t, cddr_t> > operator+= (const car_t & x, const conslist<cdar_t, cddr_t>& y ) { return conslist<car_t, conslist<cdar_t, cddr_t> >(x, y);}template < std::size_t size , typename car_t, typename cdar_t, typename cddr_t>const conslist< const car_t *, conslist<cdar_t, cddr_t> > operator+= (const car_t (&x)[ size ] , const conslist<cdar_t, cddr_t>& y) { return conslist< const car_t *, conslist<cdar_t, cddr_t> >(x, y);}
Pretty? No, but it works. You may want to provide a third version with the constness removed:
template < std::size_t size , typename car_t, typename cdar_t, typename cddr_t>const conslist< car_t *, conslist<cdar_t, cddr_t> > operator+= (car_t (&x)[ size ] , const conslist<cdar_t, cddr_t>& y) { return conslist< car_t *, conslist<cdar_t, cddr_t> >(x, y);}
Because otherwise the following will not work (this may or may not be intended):
void do_capitalize( char * c_string ) { char * i = c_string; while ( *i ) { *i = toupper( *i ); ++i; }}template < typename T >void capitalize( const T & l ) { do_capitalize( l.car() ); capitalize( l.cdr() );}template <>void capitalize( const nil & n ) {}char foo[] = "...";char bar_array[] = "...";char bar * = bar_array;capitalize( foo += nil() ); //error without non-const version, foo treated like (const char *)capitalize( bar += nil() ); //ok, bar treated like (char *)