#include // HACK AROUND g++'s INABILITY TO THROW EXCEPTIONS ON SOME MACHINES #define throw(ex) { cerr << "Threw " #ex << endl; exit(1); } // BASE CLASS class Failure { public: Failure(bool status = false) : myStatus(status) , myChecked(false) {} bool IsValid() const { myChecked = true; return myStatus; } bool Failed() const { return !IsValid(); } operator bool (void) const { return IsValid(); } protected: void CheckStatus(void) const { if (!myStatus && !myChecked) { myChecked = true; throw(Failure()); } } void SetStatus(bool status) { myStatus = status; myChecked = false; } bool myStatus; mutable bool myChecked; }; // PROXY CLASS template< class DataType > class Fallible : public Failure { public : Fallible(void) {} Fallible(const Fallible & fb, bool status) : Failure(status) , myValue(fb.myValue) {} Fallible(const DataType& value) : Failure(true) , myValue(value) {} Fallible& operator=(const DataType & value) { myValue = value; SetStatus(true); return *this; } operator DataType() const { CheckStatus(); return myValue; } friend istream& operator>>(istream& is, Fallible& f) { DataType val; if (is>>val) { f = val; } else { f.SetStatus(false); } return is; } friend ostream& operator<<(ostream& os, const Fallible& f) { f.CheckStatus(); return os << f.myValue; } friend Fallible operator<(const Fallible& a, const Fallible& b) { return Fallible(b, a.IsValid() && b.IsValid() && a.myValue < b.myValue); } private : DataType myValue; }; int main(void) { Fallible a; Fallible b; Fallible c; cout << "Enter a,b,c: "; cin >> a >> b >> c; if (a