TITLE: Doubles and non-type template parameters (Newsgroups: comp.std.c++, 5 May 98) MCKELVEY: Jim McKelvey >According to the latest public draft standard (see 14.1(3)), non-type >template-parameters may not be of floating type. > >Why this restriction? It doesn't show up in the ARM, nor in _Design and >Evolution of C++_. > >It's especially odd since floating types as type-parameters are allowed, >as well as pointers or references to floating types. CLAMAGE: clamage@Eng.Sun.COM (Steve Clamage) The ARM originally didn't allow non-type template parameters. It's new with the C++ draft standard, and at no time were floating-points allowed as non-type template parameters. It's because of the lack of definiteness in the value of a floating- point expression. Consider: If we have template < int i > class T { ... }; then each mention of T with the same value for i has the same type, and any mention of T with a different value for i has a different type: T<3> // a type T<2+1> // same type T<10/(2+1)> // same type T<2> // different type This all works because the results of integer arithmetic are well- specified. Not so with floating-point. Example: template < double x > class T { ... }; T<3.0> // a type T<0.3/0.1> // ??? T<2.9999999999999999909 + 0.0000000000000000091> // ??? Whether any two of these are the same type depends on the characteristics of floating-point arithmetic in the compiler. Since you can't know in general whether two types that appear to be the same really will be the same, floating-point constants don't have the same status as integer constants. (For example, you can't use floating-point arithmetic anywhere in an integer- constant-expression.) You could argue that you can write an integer expression whose value depends on the implementation, but that situation occurs for well- defined edge cases. No sensible programmer will use a "short" parameter if values that require more than 16 bits are to be allowed, for example. The problem is fundamental to the way floating-point is defined (or hardly defined at all) in C++. TRIBBLE: David R Tribble (private email) It's the same problem as allowing floating-point contant expressions as 'case' statement labels. For example: switch (e) { case 4.0: ... case 2.0*2.0: // Same as previous or not? ... case 1.0/3.0: ... case 0.3333333: // Same as previous or not? ... } Floating-point values are, by definition, inexact; at best they are only approximations to the decimal digits we specify in our programs, and at worst vary widely across platforms.