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

标签 c++ templates generics floating-point

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

最佳答案

简单的答案

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

14.3.2/1      Template non-type arguments      [temp.arg.nontype]

A template-argument for a non-type, non-template template-parameter shall be one of:

  • for a non-type template-parameter of integral or enumeration type, a converted constant expression (5.19) of the type of the template-parameter;

  • the name of a non-type template-parameter; or

  • a constant expression (5.19) that designates the address of an object with static storage duration and external or internal linkage or a function with external or internal linkage, including function templates and function template-ids but excluding non-static class members, expressed (ignoring parentheses) as & id-expression, except that the & may be omitted if the name refers to a function or array and shall be omitted if the corresponding template-parameter is a reference; or

  • a constant expression that evaluates to a null pointer value (4.10); or

  • a constant expression that evaluates to a null member pointer value (4.11); or

  • a pointer to member expressed as described in 5.3.1.


但是..但是..为什么!?

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

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

我们打算调用同一个函数两次,但事实可能并非如此,因为不能保证两次计算的浮点表示完全相同。


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

使用 C++11,您可以编写一些非常高级的常量表达式 (constexpr) 来计算 a 的分子/分母浮点值编译时间,然后将这两个作为单独的整数参数传递。

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

关于c++ - 为什么我不能使用浮点值作为模板参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39038242/

相关文章:

c++ - atof 函数在程序中不起作用

c++ - 为什么当我向作为 std::mem_fun() 参数的成员函数添加引用参数时编译错误?

c++ - 如何使模板参数的构造函数成为 friend ?

typescript - 通用参数限制为非数组

实现接口(interface)的java方法泛型

java - 如何在没有显式转换的情况下对返回泛型类型的方法使用 lambdaJ 的 extract()

c++ - Qt:通过 C 类将变量从 ClassA 传递到 ClassB

c++ - 在预定义的注册表项句柄上调用 RegCloseKey

c++ - 为什么更喜欢模板方法而不是依赖注入(inject)?

c++ - 派生类的散列