How to write a drop-in replacements for fundamental type (float) that override operator== in C++? -


we can not compare binary floating point directly. writting drop-in replacements class float override bulti-in compare operators::

template<class u> class float {     private:         u val;     public:         float(u v = 0): val(v) {}         operator u() const { return val; }          friend bool operator<(float a, float b) { return a.val + 1e-6 < b.val; }         friend bool operator==(float a, float b) { return !(a < b) && !(b < a); }          friend float operator*(float a, float b) { return a.val * b.val; }         template<class t>         friend float operator*(t a, float b) { return * b.val; }         template<class t>         friend float operator*(float a, t b) { return a.val * b; } }; 

now can write this::

#include<assert.h> int main() {     float<double> = 0.2, b = 0.02;     assert(a * == 2 * b); } 

however, code show unexpected behavior::

#include<complex> int main() {     std::complex< float<double> > a(0.2);     * 2.0; } 

it call float::operator*(std::complex<float<double> >, float) again , again recursive endless loop, , stack overflow. how fix this?

edit

deadmg , charles bailey point out iso/iec 14882:2011, 26.4: "the effect of instantiating template complex type other float, double, or long double unspecified."

maybe have given wrong counter example. still discuss how write drop-in replacements class fundamental type.

let me clear motivation, assert(0.1 * 0.1 == 0.01); counterintuitive. why write float class used "almost equal" behavior compare 2 floating number.

make constructor explicit.

a * 2.0; 

is implicitly constructing float, calling:

template<class t> friend float operator*(t a, float b)  {     return * b.val; } 

which in turn implicitly constructing float when invoke * operator on b.val; , recurse on there.

you need flesh out expected behaviors more before suggest complete fix.

the code used explore & test fix:

#include <iostream>  template<class u> class float {     private:         u val;     public:         explicit float(u v = 0): val(v)          {             std::cout << "constructor ";         }         operator u() const { return val; }          friend bool operator<(float a, float b) { return a.val + 1e-6 < b.val; }         friend bool operator==(float a, float b) { return !(a < b) && !(b < a); }          friend float operator*(float a, float b) { return a.val * b.val; }     template<class t>     friend float operator*(t a, float b)      {         std::cout << "here";         return * b.val;      }          template<class t>         friend float operator*(float a, t b) { return a.val * b; } };  #include<complex> int main() {     std::complex< float<double> > a(0.2);     * 2.0; } 

Comments

Popular posts from this blog

c# - SVN Error : "svnadmin: E205000: Too many arguments" -

c# - Copy ObservableCollection to another ObservableCollection -

All overlapping substrings matching a java regex -