为什么不允许double作为非类型模板参数?

时间:2013-07-18 15:17:02

标签: c++ templates c++11

2003年 - 是的, 2003 - Vandervoorde和Josuttis在他们的书“C ++模板”(第40页)中写道:

  

由于历史原因,无法将浮点文字(和简单的常量浮点表达式)用作模板参数。由于没有严重的技术挑战,因此在未来的C ++版本中可能会支持这一点。

但即使在C ++ 11下,这仍然无效:

template<double D> //error
void foo() {}

为什么没有添加?

3 个答案:

答案 0 :(得分:10)

我一直认为它与彼此匹配的实现有关。就像这两个实例相同或不同:

template class foo<10./3.>
template class foo<1./3 * 10.>

它们可能不会生成相同的双精度表示,因此编译器可能会将它们视为不同的类。然后你不能把它们分配给对方等等。

答案 1 :(得分:8)

让我们看看以下代码:

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

请参阅,D1-D2+D2对于某些值可能等于D1但对其他值不等。

更重要的是 - 根据舍入设置,它们可能相同或不相同

最后,根据编译器/架构/许多其他事情,它们可能相同或不相同。

关键是,浮点运算不足以定义模板使用(它们定义明确,但根据各种选项存在很多可能的差异)

答案 2 :(得分:6)

使用浮点数时,舍入和相等性存在很多问题。 从规范化委员会的角度来看,您需要确保两个程序在多个编译器上执行相同的操作。因此,您需要非常精确地指定浮点运算的结果。可能他们认为IEEE-754标准不够精确......

所以这不是一个问题,它是否可以实现,而是更多我们想要的精确行为。

但请注意 constexpr 接受浮点值。这通常足以用于编译时计算。