
Phil Endecott a écrit :
John Maddock wrote:
template <class T> T pi();
I have a fixed-point class. What actually happens when I call pi<fixed>() ? Presumably the implementation just does "return 3.1415...", so fixed::fixed(double) gets called. Yes my fixed class has a constructor that takes a double, and if I'm really lucky it may do the conversion at compile time - but more likely it will happen at run time. I would get the same code if you just declared "const double pi = 3.1415" (or #defined it).
My 64-bit fixed point type can store more digits of PI than a 64-bit floating point value. But I'm not aware of any way of filling those extra digits [ignoring the existence of long double]. Similarly if I had an arbitrary precision (i.e. variable length) type, how would it be constructed from the 100-digit constants that you mention without support from the language (or maybe macros)?
(As for the actual constants, the only ones I find myself using are pi and the approximate radius of the earth.)
Sorry if i soem up with a bad or already proposed solution. I had to handle such named constant in soem code with the same ste of constraints (usability and casting to user-defined type). What I did was to have class of constants that are build based on a constant ID and expose a tempalte operator T: template<class ID> class constant { template<class T> operator T() const { return cast<T>(ID::Value()); } // proper unary operator and so on }; ID class are the one containing the actual consatnt value and a "default type" : class pi_id { typedef long double type; static inline Value() { return 3.1415........; } }; The T() operator call a cast function which is in fact a polymorphic function object that uses tag dispatching to either just perform a cast or to call a user-defined casting operation. Those user defined operator can be overloaded on the constant id if needed (for example if you have special algorithm to compute pi with fixed representation but use a cast for other constant). Those constant are then statically defined as POD constant : constant<pi_id> pi_ = {}; How to use those constant ? It rather simple. Things like double k = pi_; int u = ten_; works as intended by auto-casting the valeu to the destination type. You can force a constant to be of a given type : abs( float(log2_) ); Alternatively, the basic operator (+,-,*,/,unary -, ~, ! and comparison) are overlaod to autocast the constant into a proper type when used like : double k,v; k = v + pi_; bool test = x > log10_; A set of result_of enabled traits also allows to computes the correct type of a constant when used in a complex expression. Most constant type-cast is performed at compile-time, unless if you use a user-defined type-casting overload. I am overthinking it or could this be viable ? -- ___________________________________________ Joel Falcou - Assistant Professor PARALL Team - LRI - Universite Paris Sud XI Tel : (+33)1 69 15 66 35