views:

100

answers:

3

Section 4.3 of C++ Templates states 'Not being able to use floating-point literals (and simple constant floating-point expressions) as template arguments has historical reasons.'

Similarly,

$14.1/7 states - "A non-type template-parameter shall not be declared to have floating point, class, or void type. [ Example:

template<double d> class X; // error
template<double* pd> class Y; // OK
template<double& rd> class Z; // OK"
  1. What is the historical reason that is being talked about in the book in the above quote?

  2. Looking at why Y and Z are valid but not X, is the whole challenge related to having non type template parameters of floating type got to do anything with pointers/references?

  3. Why template non type parameters can not be of class type?

+2  A: 

Floating point numbers have no universal representation (and some values can't even be represented without precision losses since its based on approximation) and therefore can be different from platform to platform causing the same C++ code generate different templates on different platforms.

(One can say as C++ supports cross compilation without requiring the compiler to fully emulate the floating point arithmetic of the target machine. Allowing float or double as a template parameter would invalidate this.)

template<float F> 
float squared_float() 
{ 
return F * F;
}

For example, squared_float<1.0> might be the same function as squared_float<1.00000001> on some implementations, whereas on others they would be two different functions.


A reference to a float means the compiler can optimize it as it knows it's value and that it should never change.

For pointer, well its just another architecture-dependent (32bit/64bit) data type that has nothing to do with float.

YeenFei
On a given platform however that should not be an issue. It may however affect portability, which is true of so many other features in the language e.g. sizeof(int)
Chubsdad
+5  A: 

It could be hard to pick the right template instantitiation, because of possible roundoff errors .

Consider the following:

template<float n> 
void f(n) {...}  //Version 1

template<0.3333> 
void f() { ...} // Version 2:Specialization for 0.3333 

f(1/3); -> Which version would be called?

Consider the following code:

template <float f> class foo { ... }; 
foo<1E6 + 1E-6> my_foo; 

" What should the compiler generate? The compiler has to know about the details of target floating-point architecture to be able to run instantiate the template. This is easy enough if the compiler is running on the target architecture, it can just do the calculation and find out the answer, but if you are cross-compiling, the compiler would have to be able to synthesise the floating point behaviour of every intended target architecture. And thankfully the Standards Committee decided that this would be unreasonable. "

Shamelessly copied from here.

Why template non type parameters can not be of class type

As per my understanding a non-type paramater cannot be of class type because there may be more than one implementation of a class. For example

template <typename T>   
class demo{...};

template <>    
class demo<int>{...};


template <typename T, demo d> //which demo?? demo<T> or demo<int>
class Example{...};

Local classes cannot be used as template parameters because they don't have external linkage.

Prasoon Saurav
0.3333 is of type 'double' isn't it which is same as the type of 1/3? So the compiler can chose the specialization for 'double' with default as <0.3333>
Chubsdad
that sounds reasonable, IEEE repr was introduced in 1985, the same time C++ became "official", so perhaps there was not standard mathematics for floating-point
aaa
Prasoon Saurav
I know that 'value representation of floating point types is implementation defined'. Is there any issue with 1E6 + 1E-6? Also I did not quiet get the issue with cross compilation
Chubsdad
Are class types not supported because they may in turn contain 'floating point' types and hence run into the same issue?
Chubsdad
@Chubsdad : `1E6 + 1E-6` may not be stored precisely as a post in that thread says. Your compiler `should` be able to synthesise the floating point behaviour of every intended architecture. But how would that be possible without knowing the exact architecture(in case of cross compilation), does that make sense?
Prasoon Saurav
@Chubsdad : Wait, my my last comment was incorrect (so deleted it). Local classes/structs cannot be used as template parameters because [they have internal(not external) linkage](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1427.pdf), which currently would cause problems for template instantiation. I think C++1x would allow local classes to be used a template parameters.
Prasoon Saurav
But the quote in OP does not mention only about local class/structs. It says non type parameters are not allowed to be of class type
Chubsdad
@Chubsdad : Updated my answer in response to your comment.
Prasoon Saurav
A: 

The exact encoding of floating point values is more subject to quirks of individual CPUs. For example, in evaluating a supposedly constant expression, should a CPU use higher-precision 80bit CPU registers and only round back to 64-bit at the end? If one compilers says yes and another no - the template will get two distinct instantiations. But, some other compiler might only have 64-bit registers, and perhaps different CPUs might vary by an epsilon value. The order in which some compiler chooses to evaluate an expression, or whether a library was compiled using a floating-point emulation library etc. might cause such mis-matches. Further, floating point numbers have some strange edge cases: positive and negative 0 etc., for which behaviour would have to be defined.

Interestingly, Walter Bright (of Digital Mars) thought that was all crap and allows floating point constants in D... guess he's been getting some real world experience of the consequences that would be useful to the C++ community, but I haven't heard recently.

Tony
there are some MPL stuff in boost vault which allow FP constants.
aaa
hmmm... I avoid MPL - annoyed boost refused to house Loki while the available online docs for MPL are the worst in the whole boost collection and IMHO a blatant "I'm gonna make some money here because I'm in control of boost" advert for books, while other boost authors are expected to actually live by the general "share it freely with the community" spirit boost likes to publicly espouse
Tony
[We could ask him](http://stackoverflow.com/users/33949/walter-bright)
Johannes Schaub - litb
@Johannes: Yes, but he's already commented on this a while back on comp.lang.c++ or ~.moderated... anyone interested might search there before bothering him.
Tony