Listing 1: Zobel's argument setting technique


// Copy and paste would be worse,
// so the macro is Ok
#define  DECLCPAR(type,name)  \
    public:  PARMS &name##Set(type x)\
        {name = x; return *this;}\
    private: type  name; 

// system calls to allocate and free the
// resource refered to by SYSRES::handle
int CreateSysRes(int, int, float);
void DestroySysRes(int);

// SYSRES encapsulates some system resource
// (i.e. file, window, port)
class SYSRES
{
public:
   class PARMS
   {       
   public:        
      // default parameters
      PARMS(void):
         ival1(-1),
         ival2(0),         
         fval(99.9)  {}
   private:             
   friend class SYSRES;    
      
      DECLCPAR(int,  ival1)      
      DECLCPAR(int,  ival2)      
      DECLCPAR(float,fval)
   };           

   SYSRES(const PARMS &parms = PARMS()):
      handle(CreateSysRes(parms.ival1,
                        parms.ival2,
                        parms.fval))
      {}             
   ~SYSRES()
      {DestroySysRes(handle);}

private:
   int   handle;
}; 

void fun(const SYSRES &);

int main()
{
   SYSRES   res   =
      SYSRES::PARMS().ival1Set(20).fvalSet(0.7);

   fun(SYSRES::PARMS().ival2Set(9));   
   
   return 1;
}                       
//End of File