Why is double not allowed as a non-type template p

2020-07-03 04:53发布

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?

3条回答
混吃等死
2楼-- · 2020-07-03 05:13

When using floating point numbers, there is are lots of problem with rounding and equality. From the point of view of the normalizing committee, you need to ensure that two programs execute the same on several compilers. Therefore you need to specify very precisely what is the result of floating point operation. Probably they felt that the IEEE-754 norm is not precise enough...

So this is not a question of whether or not it is implementable but more of what precise behavior we want to have.

Note however that constexpr accept floating point values. This is usually enough for compile time computation.

查看更多
叛逆
3楼-- · 2020-07-03 05:17

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)

查看更多
贼婆χ
4楼-- · 2020-07-03 05:29

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.

查看更多
登录 后发表回答