Ticket #12299: main.cpp

File main.cpp, 3.8 KB (added by Ulrich Mutze <ulrichmutze@…>, 6 years ago)
Line 
1/*
2Ulrich Mutze 2016-06-23
3
4Title:
5------
6User-defined conversion operator from a wrapper class to a
7boost/multiprecision floating-point type does not compile.
8
9The observation:
10---------------
11With the first of the two typedefs in action the file does not compile.
12Commentarizing the first typedef and activating the second lets
13everything work fine.
14According to the rules of C++ it should work in both cases.
15That it does not has probably to be considered a bug in the
16boost/multiprecision class system. It conflicts with the statement
17"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."
18of the documentation to cpp_bin_float.
19
20The context:
21-----------
22In 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
23 typedef double (or float or long double) R;
24Here R stands for the set of real numbers as used in mathematics and not
25for the statistics-oriented software system R.
26In developing classes to be used in physics simulations it turned out
27often to be necessary to give a class an additional R-typed member.
28Since the built-in types get not automatically initialized, in such a case
29I had to extend the constructor initializer list in all the many constructors of my class by hand which was tedious and error-prone.
30So I decided to have floating-point data members in the form
31 R1 x_;
32with a wrapper class R1 as defined in the following code. Using x_
33somewhere in an arithmetic expression would automatically convert it to R
34just as I had introduced it as
35 R x_;
36When I enabled multiprecision my first option was
37 typedef mpfr::mpreal R;
38and everything worked well with this "drop-in replacement".
39See my work:
40 Precision-dependent symmetry breaking in simulated motion of
41 polyspherical grains (2009)
42 http://uuu.ma.utexas.edu/mp_arc/c/09/09-113.pdf
43Ironically the wrapper R1 was no longer necessary in principle since now
44R-typed data members would have been initialized as R(0) automaticaly.
45However, the bit of extra complexity did no harm and was still necessary
46for the normal mode of my programs in which R was an alias for double.
47Of course, my expectation was that replacing mpreal by any of the
48boost multiprecision floating point types would work the same way. Unfortunately this turned out to be a pre-mature expectation. My hope is
49that digging out the reason for this strange behavior will give hints
50how the boost multiprecision floating-point types can be promoted to
51real "drop-in replacements" of type double.
52
53The code:
54---------
55*/
56#include <iostream>
57#include <boost/multiprecision/cpp_bin_float.hpp>
58
59using namespace std;
60using namespace boost::multiprecision;
61
62typedef number<cpp_bin_float<50>, et_off > R;
63//typedef double R;
64
65//------------------------ class R1 ---------------------------------------
66class R1{ // wrapper class for R
67 R x_;
68public:
69 R1(void):x_(0.){}
70// explicit conversion R --> R1
71 explicit R1(R const& a):x_(a){}
72// automatic conversion operator R1 --> R
73 operator R()const{ return x_;}
74};
75
76int main()
77{
78 cout.precision(50);
79 R x=9.123456789123456789123456789;
80 R y=5.678912345678901234567890123;
81 R1 x1(x);
82 R1 y1(y);
83 R sum=x1+y1;
84 // This has to work since x1 and x2 can be converted to
85 // instances of R. It actually works for typedef double R;.
86 // My German-speaking system says for
87 // typedef number<cpp_bin_float<50>, et_off > R;
88 // 'Keine Übereinstimmung für >>operator+<< in >>x1+y1<<'
89 // my translation:
90 // 'no match for >>operator+<< in >>x1+y1<<'.
91 cout << " x = "<<x<<endl;
92 cout << " y = "<<y<<endl;
93 cout << " sum = "<<sum<<endl;
94 return 0;
95}