rae@gpu.utcs.toronto.edu (Reid Ellis) (12/21/90)
I posted the following earlier, but I gave it a distribution of "local" by mistake. Sorry if anyone sees this twice! --- I've been trying to create pseudo-base-types -- that is, classes which emulate almost all of the behaviour of a base type -- and have run into what appears to be a bug. When I compile the source below on an SGI machine, I have no problem. If I compile it on a Macintosh, I get the error shown below. It looks as if the compiler is trying to cast a double to an int for some reason. Can't figure why, since both the parameter and the expected return value are both unambiguously double. File "fakeInt.cp"; line 48 # error: two standard conversions possible for abs(): double (double ) and int (int ) Here's my cfront version: << CFront Version 1.0 (9/11/90; AT&T 2.0) *Apple Computer, Inc. 1989-90 >> ^-- Mac '(c)' character Note that on an SGI, the "#expr" preprocessor directive does not work, thus the #ifdef's.. ---8<-----c-u-t-----h-e-r-e------->8--------- #include <stream.h> #ifdef sgi # define try(expr) \ if(expr) cout << "yes "; else cout << "no "; cout << "expr \n" ; # define show(type, expr) \ cout << "expr = " << (type &)(expr) << '\n'; #else # define try(expr) \ if(expr) cout << "yes "; else cout << "no "; cout << #expr "\n" ; # define show(type, expr) \ cout << #expr " = " << (type &)(expr) << '\n'; #endif inline double abs(double d) { return (d >= 0.0) ? d : -d; } inline int abs(int d) { return (d >= 0.0) ? d : -d; } struct Tint { Tint() {} Tint(const int &i) : value(i) {} Tint(const Tint &t) : value(t.value) {} operator int &() { return value; } int operator==(const Tint &t) const // this is a bit whimsical ... { return abs(value - t.value) <= 1; } int operator==(const int &i) const { return value == i; } private: int value; }; struct Tdouble { Tdouble() {} Tdouble(const double &d) : value(d) {} Tdouble(const Tdouble &d) : value(d.value) {} static const double kEpsilon; operator double &() { return value; } int operator==(const Tdouble &d) const { return (abs(value - d.value) < kEpsilon); } // <=== line 48 int operator==(const double &d) const { return value == d; } private: double value; }; const double Tdouble::kEpsilon = 0.1; const double kInit = 1.0; const double kInit2 = 1.003; void main() { int i1 = 1; int i2 = 2; Tint x1 = 1; Tint x2 = 2; // if I try saying "d1 = 1.0" below, it complains about // "cannot make a Tdouble from a long double".. Tdouble d1 = kInit; Tdouble d2 = kInit2; show(int, i1); show(int, i2); show(int, x1); show(int, x2); show(double, d1); show(double, d2); try(i1 == x1); try(x1 == x2); try(x2 == x1); try(d1 == d2); d2 += 0.1; show(double, d2); try(d1 == d2); }