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