[comp.lang.c++] overloading operators void*

neath@solar-1.stars.flab.Fujitsu.JUNET (08/15/89)

One of the problems that I have faced several  times during the developlment of
various C++  classes is the   need to return  two values  from some  method  or
function.  This typically is the case where I  needed to return  a reference to
some object and also indicate whether the operation(s) attempted were sucessful
or not. There is direct language support for this in Lisp, but no such facility
exists in C++, or so I thought!

An expression whose value is used in any type of logical statement has its type
promoted to int before the test for zero or non-zero is made.   This is because
FALSE is defined by the language to be zero and TRUE is defined to be non-zero.
It is possible in C++ to make any expresion (ie.  the  result of any overloaded
operator, method, or friend function) be promoted to type  int  just before the
test is made. This can be accomplished by either operator int() or void*().

The  following example illustrates  this  feature.  The class "positive_int" is
defined to support positive integers only. The private data section contains an
int slot for the value and a Boolean slot to maintain the state of  the object.
Operations and methods defined for the  class update the  state slot as needed.
The inline operator void*() method casts  the state slot to  an int and returns
the result.  The  operator-=  method implements subtraction for  the class.  

In the  main() section of the program  below, a positive_int object  is defined
with an initial value of three. The operator-=  method is invoked with  a value
of five.  If the result of such an operation  is non-negative, the new value is
computed and a reference  to the updated  object is  returned.  However, if the
operation would result in a negative  number (as  in this case), the state slot
is set to FALSE and  the non-updated object  is returned. The void* operator is
automatically invoked by the  compiler on  the result of the  expression. Since
the state slot was set to  FALSE, the expression  is evaluated as  zero and the
condition fails.
   
   #include <stream.h>
   
   typedef enum { FALSE, TRUE } Boolean;
   
   class positive_int {
   private:
     Boolean state;
     int data;
   public:
     positive_int (int value) {
       this->data = value;
       this->state = TRUE;
     }
   
     positive_int& operator-= (int i) {
       if (i > this->data)
         this->state = FALSE;
       else
         this->data -= i;
       return *this;
     }
       
     inline void* operator void* () {
       return (void*) this->state;
     }
   };
   
   int main (void) {
     positive_int x(3);
   
     if (x -= 5)
       cout << "State: TRUE\n";
     else
       cout << "State: FALSE\n";
   }
     
If an object has an internal  state slot, then  by overloading operator void*()
to behave in a manner similar to  that shown above,  it is possible for methods
and friend  functions to perform  an operation  and return  a reference to  the
object as well as a TRUE/FALSE status.  This may alleviate the need for raising
an exception and instead allow  the  application to handle the  problem in some
other  way.  Incidentally,  such  a mechanism is  used in the AT&T stream class
operator>> method to single an EOF condition  while  also returning a reference
to the input stream, thus facilitating statements like:

   while (cin >> i) {
      :::
   }

Now, I mentioned  above  that both operator int() and  operator  void*() can be
overloaded to provide  this functionality.   For cases like   the  positive_int
class, I want to use operator int() to return the integer  value  stored in the
object so that I can mix them with other int  expressions.  Unfortunately, if I
overload both operator void*() and operator int(), cfront 1.2 complains with:

   2 possible conversions for positive_int object in if expression

Is it possible in cfront 2.0 to overload both operator void*() and int() in the
same class to implement  this type of  functionality? Is this  legal? Are there
alternate mechanisms for accomplishing this task?

Regards
Martin Neath <neath@dsg.ti.com>
------------------------------------------------------------------------
 DISCLAIMER: As always, the opinions expressed above are strictly my own
 and do not reflect those of my employer, Texas Instruments.
------------------------------------------------------------------------