为了账号安全,请及时绑定邮箱和手机立即绑定

为什么我不能使用浮点值作为模板参数?

为什么我不能使用浮点值作为模板参数?

C++
凤凰求蛊 2019-07-30 15:53:31
为什么我不能使用浮点值作为模板参数?当我尝试float用作模板参数时,编译器会为此代码而烦恼,同时int工作正常。是因为我不能float用作模板参数吗?#include<iostream>using namespace std;template <class T, T defaultValue>class GenericClass{private:     T value;public:     GenericClass()     {         value = defaultValue;     }     T returnVal()     {         return value;     }}; int main(){     GenericClass <int, 10> gcInteger;     GenericClass < float, 4.6f> gcFlaot;     cout << "\n sum of integer is "<<gcInteger.returnVal();     cout << "\n sum of float is "<<gcFlaot.returnVal();     return 0;       }错误:main.cpp: In function `int main()': main.cpp:25: error: `float' is not a valid type for a template constant parameter main.cpp:25: error: invalid type in declaration before ';' token main.cpp:28: error: request for member `returnVal' in `gcFlaot',                     which is of non-class type `int'我正在阅读Ron Penton撰写的“游戏程序员的数据结构”,作者传递了一个float,但是当我尝试它时似乎没有编译。
查看完整描述

3 回答

?
千万里不及你

TA贡献1784条经验 获得超9个赞

当前的C ++标准不允许float(即实数)或字符串文字用作模板非类型参数。您当然可以使用floatchar *类型作为普通参数。

也许作者使用的编译器不遵循现行标准?


查看完整回答
反对 回复 2019-07-30
?
回首忆惘然

TA贡献1847条经验 获得超11个赞

简单的回答

该标准不允许浮点作为非类型模板参数,可以在C ++ 11标准的以下部分中阅读;

14.3.2 / 1模板非类型参数[temp.arg.nontype]

非类型非模板模板参数的模板参数应为以下之一:

  • 对于整数或枚举类型的非类型模板参数,模板参数类型的转换常量表达式(5.19);

  • 非类型模板参数的名称; 要么

  • 一个常量表达式(5.19),用于指定具有静态存储持续时间和外部或内部链接的对象的地址,或具有外部或内部链接的函数,包括函数模板和函数模板-id,但不包括非静态类成员,表示(忽略)括号)as&id-expression,除非如果名称引用函数或数组,可以省略&,如果相应的template-parameter是引用,则省略; 要么

  • 一个常量表达式,其值为空指针值(4.10); 要么

  • 一个常量表达式,其值为null成员指针值(4.11); 要么

  • 指向成员的指针,如5.3.1中所述。


但是..但是为什么!?

这可能是由于浮点计算无法以精确的方式表示。如果它被允许它可能/会在做这样的事情时导致错误/奇怪的行为;

func<1/3.f> (); func<2/6.f> ();

我们打算两次调用相同的函数,但这可能不是这种情况,因为两个计算的浮点表示不能保证完全相同


我如何将浮点值表示为模板参数?

随着C++11你可以写一些非常先进的常量表达式constexpr),将计算出的浮动值的分子/分母编译时间,然后通过这两个作为单独的整数参数。

请记住定义某种阈值,使浮点值彼此接近,产生相同的分子/分母,否则它有点无意义,因为它会产生前面提到的相同结果,作为不允许浮点值为 非类型的原因模板参数


查看完整回答
反对 回复 2019-07-30
?
慕标5832272

TA贡献1966条经验 获得超4个赞

只是提供这是一个限制的原因之一(至少在目前的标准中)。

匹配模板特化时,编译器会匹配模板参数,包括非类型参数。

就其本质而言,浮点值并不精确,并且C ++标准未指定它们的实现。因此,很难确定两个浮点非类型参数何时真正匹配:

template <float f> void foo () ;void bar () {
    foo< (1.0/3.0) > ();
    foo< (7.0/21.0) > ();}

这些表达式不一定产生相同的“位模式”,因此不可能保证它们使用相同的特化 - 没有特殊的措辞来涵盖这一点。


查看完整回答
反对 回复 2019-07-30
  • 3 回答
  • 0 关注
  • 1445 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信