Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is double not allowed as a non-type template parameter? [duplicate]

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?

like image 328
roger.james Avatar asked Jul 18 '13 15:07

roger.james


People also ask

Which parameter is allowed for non-type template?

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.

Can we use non-type parameters as argument templates?

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.

What can the template parameter in C++ template definition be?

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.

Can a template be a template parameter?

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.


2 Answers

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.

like image 157
JoshG79 Avatar answered Sep 23 '22 05:09

JoshG79


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)

like image 36
rabensky Avatar answered Sep 23 '22 05:09

rabensky