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

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

当我尝试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,但是当我尝试它时似乎没有编译。


凤凰求蛊
浏览 1446回答 3
3回答

千万里不及你

当前的C ++标准不允许float(即实数)或字符串文字用作模板非类型参数。您当然可以使用float和char *类型作为普通参数。也许作者使用的编译器不遵循现行标准?

回首忆惘然

简单的回答该标准不允许浮点作为非类型模板参数,可以在C ++ 11标准的以下部分中阅读;14.3.2 / 1模板非类型参数[temp.arg.nontype]非类型非模板模板参数的模板参数应为以下之一:对于整数或枚举类型的非类型模板参数,模板参数类型的转换常量表达式(5.19);非类型模板参数的名称;&nbsp;要么一个常量表达式(5.19),用于指定具有静态存储持续时间和外部或内部链接的对象的地址,或具有外部或内部链接的函数,包括函数模板和函数模板-id,但不包括非静态类成员,表示(忽略)括号)as&id-expression,除非如果名称引用函数或数组,可以省略&,如果相应的template-parameter是引用,则省略;&nbsp;要么一个常量表达式,其值为空指针值(4.10);&nbsp;要么一个常量表达式,其值为null成员指针值(4.11);&nbsp;要么指向成员的指针,如5.3.1中所述。但是..但是为什么!?这可能是由于浮点计算无法以精确的方式表示。如果它被允许它可能/会在做这样的事情时导致错误/奇怪的行为;func<1/3.f>&nbsp;();&nbsp;func<2/6.f>&nbsp;();我们打算两次调用相同的函数,但这可能不是这种情况,因为两个计算的浮点表示不能保证完全相同。我如何将浮点值表示为模板参数?随着C++11你可以写一些非常先进的常量表达式(constexpr),将计算出的浮动值的分子/分母编译时间,然后通过这两个作为单独的整数参数。请记住定义某种阈值,使浮点值彼此接近,产生相同的分子/分母,否则它有点无意义,因为它会产生前面提到的相同结果,作为不允许浮点值为&nbsp;非类型的原因模板参数。

慕标5832272

只是提供这是一个限制的原因之一(至少在目前的标准中)。匹配模板特化时,编译器会匹配模板参数,包括非类型参数。就其本质而言,浮点值并不精确,并且C ++标准未指定它们的实现。因此,很难确定两个浮点非类型参数何时真正匹配:template&nbsp;<float&nbsp;f>&nbsp;void&nbsp;foo&nbsp;()&nbsp;;void&nbsp;bar&nbsp;()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;foo<&nbsp;(1.0/3.0)&nbsp;>&nbsp;(); &nbsp;&nbsp;&nbsp;&nbsp;foo<&nbsp;(7.0/21.0)&nbsp;>&nbsp;();}这些表达式不一定产生相同的“位模式”,因此不可能保证它们使用相同的特化 - 没有特殊的措辞来涵盖这一点。
打开App,查看更多内容
随时随地看视频慕课网APP