/* Ulrich Mutze 2016-06-23 Title: ------ User-defined conversion operator from a wrapper class to a boost/multiprecision floating-point type does not compile. The observation: --------------- With the first of the two typedefs in action the file does not compile. Commentarizing the first typedef and activating the second lets everything work fine. According to the rules of C++ it should work in both cases. That it does not has probably to be considered a bug in the boost/multiprecision class system. It conflicts with the statement "It acts as an entirely C++ (header only and dependency free) floating-point number type that is a drop-in replacement for the native C++ floating-point types, but with much greater precision." of the documentation to cpp_bin_float. The context: ----------- In my large C++ class system ( referred to as C+- in uuu.ulrichmutze.de) which originally did not enable multiprecision, I typedefed the floating-point type to be used througout the entire code base as typedef double (or float or long double) R; Here R stands for the set of real numbers as used in mathematics and not for the statistics-oriented software system R. In developing classes to be used in physics simulations it turned out often to be necessary to give a class an additional R-typed member. Since the built-in types get not automatically initialized, in such a case I had to extend the constructor initializer list in all the many constructors of my class by hand which was tedious and error-prone. So I decided to have floating-point data members in the form R1 x_; with a wrapper class R1 as defined in the following code. Using x_ somewhere in an arithmetic expression would automatically convert it to R just as I had introduced it as R x_; When I enabled multiprecision my first option was typedef mpfr::mpreal R; and everything worked well with this "drop-in replacement". See my work: Precision-dependent symmetry breaking in simulated motion of polyspherical grains (2009) http://uuu.ma.utexas.edu/mp_arc/c/09/09-113.pdf Ironically the wrapper R1 was no longer necessary in principle since now R-typed data members would have been initialized as R(0) automaticaly. However, the bit of extra complexity did no harm and was still necessary for the normal mode of my programs in which R was an alias for double. Of course, my expectation was that replacing mpreal by any of the boost multiprecision floating point types would work the same way. Unfortunately this turned out to be a pre-mature expectation. My hope is that digging out the reason for this strange behavior will give hints how the boost multiprecision floating-point types can be promoted to real "drop-in replacements" of type double. The code: --------- */ #include #include using namespace std; using namespace boost::multiprecision; typedef number, et_off > R; //typedef double R; //------------------------ class R1 --------------------------------------- class R1{ // wrapper class for R R x_; public: R1(void):x_(0.){} // explicit conversion R --> R1 explicit R1(R const& a):x_(a){} // automatic conversion operator R1 --> R operator R()const{ return x_;} }; int main() { cout.precision(50); R x=9.123456789123456789123456789; R y=5.678912345678901234567890123; R1 x1(x); R1 y1(y); R sum=x1+y1; // This has to work since x1 and x2 can be converted to // instances of R. It actually works for typedef double R;. // My German-speaking system says for // typedef number, et_off > R; // 'Keine Übereinstimmung für >>operator+<< in >>x1+y1<<' // my translation: // 'no match for >>operator+<< in >>x1+y1<<'. cout << " x = "<