使用float作为非类型的模板特化

Chu*_*dad 11 c++ templates non-type

C++模板的第4.3节 声明"不能使用浮点文字(和简单的常量浮点表达式)作为模板参数具有历史原因."

同样的,

$ 14.1/7状态 - "非类型模板参数不应声明为具有浮点,类或void类型.[示例:

template<double d> class X; // error
template<double* pd> class Y; // OK
template<double& rd> class Z; // OK"
Run Code Online (Sandbox Code Playgroud)
  1. 上述引文中正在讨论的历史原因是什么?

  2. 看看为什么Y和Z有效但不是X,整个挑战与浮动类型的非类型模板参数是否与指针/引用有关?

  3. 为什么模板非类型参数不能是类类型?

Pra*_*rav 10

由于可能的舍入错误,可能很难选择正确的模板即时关系.

考虑以下:

template<float n> 
void f(n) {...}  //Version 1

template<0.3333> 
void f() { ...} // Version 2:Specialization for 0.3333 
Run Code Online (Sandbox Code Playgroud)

f(1/3); - >将调用哪个版本?

请考虑以下代码:

template <float f> class foo { ... }; 
foo<1E6 + 1E-6> my_foo; 
Run Code Online (Sandbox Code Playgroud)

"编译器应该生成什么?编​​译器必须知道目标浮点体系结构的细节才能运行实例化模板.如果编译器在目标体系结构上运行,这很容易,它只需要进行计算并找到答案,但如果你是交叉编译,编译器必须能够综合每个预期目标架构的浮点行为.值得庆幸的是标准委员会认为这是不合理的."

这里无耻地复制.

为什么模板非类型参数不能是类类型

根据我的理解,非类型参数不能是类类型,因为类可能有多个实现.例如

template <typename T>   
class demo{...};

template <>    
class demo<int>{...};


template <typename T, demo d> //which demo?? demo<T> or demo<int>
class Example{...};
Run Code Online (Sandbox Code Playgroud)

本地类不能用作模板参数,因为它们没有外部链接.


Yee*_*Fei 5

浮点数没有通用表示(有些值甚至不能在没有精度损失的情况下表示,因为它基于近似)因此可能因平台而异,导致相同的C++代码在不同平台上生成不同的模板.

(可以说C++支持交叉编译而不需要编译器完全模拟目标机器的浮点运算.允许float或double作为模板参数会使此无效.)

template<float F> 
float squared_float() 
{ 
return F * F;
}
Run Code Online (Sandbox Code Playgroud)

例如,在某些实现中,squared_float <1.0>可能与squared_float <1.00000001>的功能相同,而在其他实现中,它们可能是两个不同的函数.


A reference to a float意味着编译器可以优化它,因为它知道它的值并且它永远不会改变.

因为pointer,它只是另一个与浮点数无关的架构相关(32位/ 64位)数据类型.