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. ------------------------------------------------------------------------