Boost logo

Boost :

From: Daryle Walker (dwalker07_at_[hidden])
Date: 2002-11-24 18:49:06


[Apologies to the computer scientist who came up with that phrase
(w.r.t. GOTOs)]

I haven't looked at the serialization library that was just up for
review, but some of the comments I saw on this list suggested that the
archive classes use virtual operators for reading or writing the basic
types. I have a book called _C++ FAQs_ (2nd ed.) that has a blurb
about a virtual assignment operator. I think the concept is too funky
because:

1. You have no choice about an operator's interface, even if that
interface isn't the best for inheritance.
2. The dispatch interactions could introduce subtleties.

I have a better idea: use the "concrete function calls a virtual
function" idiom. Maybe it could be like:

class my_writer
{
public:
     //...

     // The main writing functions; they secretly call their private
     // do_write version;
     my_writer & operator <<( char x );
     my_writer & operator <<( signed char x );
     my_writer & operator <<( unsigned char x );
     my_writer & operator <<( signed short x );
     my_writer & operator <<( unsigned short x );
     my_writer & operator <<( unsigned x );
     my_writer & operator <<( int x );
     my_writer & operator <<( unsigned long x );
     my_writer & operator <<( signed long x );
     my_writer & operator <<( float x );
     my_writer & operator <<( double x );
     my_writer & operator <<( long double x );
     my_writer & operator <<( wchar_t x );

#ifdef Long-Longs
     my_writer & operator <<( unsigned long long x );
     my_writer & operator <<( signed long long x );
#endif

     my_writer & operator <<( void *x );

     // do cv-variants too; all of them call the void* version
     template < typename T >
     my_writer & operator <<( T *x );

     // don't do this, explode T for char, signed char, unsigned char,
     // and wchar_t; they determine the string length, then call the
     // same private do_write function the singleton versions do
     template < typename T >
     my_writer & write_as_string( T *x );

     // don't do this, use the N-argument only and explode T for
     // each basic type; they call the same private do_write function
     // the singleton versions do
     template < typename T, std::size_t N >
     my_writer & write_as_array( T (&a)[N] );

private:
     // don't do this, explode T for each basic type
     // (actually, you can't do this since virtual & templates don't mix)
     template < typename T >
     virtual void do_write( T *a, std::size_t n = 1 );
};

Remember that this idiom allows pre- and post-processing around the
virtual call, without the override's author being able to
(accidentally) kill that processing.

Daryle


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