In 2003 - yes, 2003 - Vandervoorde and Josuttis wrote this in their book "C++ Templates" (p. 40):
Not being able to use floating-point literals (and simple constant floating-point expressions) as template arguments has historical reasons. Because there are no serious technical challenges, this may be supported in future versions of C++.
But this still doesn't work, even under C++11:
template<double D> //error
void foo() {}
Why was this not added?
Which parameter is legal for non-type template? Explanation: The following are legal for non-type template parameters:integral or enumeration type, Pointer to object or pointer to function, Reference to object or reference to function, Pointer to member.
A non-type template argument provided within a template argument list is an expression whose value can be determined at compile time. Such arguments must be constant expressions, addresses of functions or objects with external linkage, or addresses of static class members.
In C++ this can be achieved using template parameters. A template parameter is a special kind of parameter that can be used to pass a type as argument: just like regular function parameters can be used to pass values to a function, template parameters allow to pass also types to a function.
Templates can be template parameters. In this case, they are called template parameters. The container adaptors std::stack, std::queue, and std::priority_queue use per default a std::deque to hold their arguments, but you can use a different container.
I had always assumed it had to do with matching implementations against each other. Like are these two instances the same or different:
template class foo<10./3.>
template class foo<1./3 * 10.>
They may not generate the same double-precision representation, so the compiler might think of them as different classes. Then you couldn't assign them to each other, etc.
Lets look at the following code:
template<double D> int f(){
static int i=0;
++i;
return i;
}
...
#define D1=...
#define D2=...
cout << f<D1>()<<endl; // returns 1
cout << f<D1-D2+D2>()<<endl; // may return 1 or 2, depending on many things
See, D1-D2+D2
may be equal to D1
for some values but not equal for others.
More importantly - they may be equal or not depending on the rounding settings
And finally, they may be equal or not depending on compilers / architectures / many other things.
The point is, floating point operations are not well enough defined for template use (they are well defined, but there is a lot of possible variance depending on various options)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With