元编程中有哪些数学运算符可用?

6
我很震撼地看到了Todd Veldhuizen的元编程指南中的最后一个例子,其中三角函数如sincos在编译时被预先计算。说实话,这让我大吃一惊,如果您正在编写执行大量此类操作的代码(就像我一样),那么这可能会对性能产生重大影响。
问题1
但是,这让我想知道可运行工具(调用实际的数学库函数,如sincos)与仅作为编译时数学运算符可用之间的界限在哪里。
Todd的示例需要使用普通算术手动计算三角函数。
那么,我应该假设编译器能够处理所有普通数学函数*+-/,但没有其他函数吗?
问题2
在这种情况下,您只能获得整数的编译时结果,对于sincos计算,是吗?也就是说,您不能预编译像sin 45.5这样的结果,对吗?
或者,如果模板只能接受整数作为参数,您可以在类中获取多个整数并将它们转换为float,例如传递1 2 3 并生成1.23 来获取浮点值的sin
1个回答

2

问题1

然而,这让我想知道在什么情况下可以作为运行时工具使用(调用实际的数学库函数,如sin或cos),以及什么情况下只能作为编译时数学运算符使用。

  • 如果命名函数被声明为constexpr,遵守constexpr规则并使用编译时常量调用,则只能在编译时使用。
  • 用户定义的数据类型只有通过从编译时常量构造的constexpr构造函数来构造时才能在编译时使用。
  • 任何作用于编译时常量内置类型的内置运算符都会产生编译时常量。
  • 如果原始值是编译时常量,则任何内置类型之间的类型转换都会产生编译时常量。

因此,不仅限于四个数学运算符,还可以使用%和其他运算符,以及模板元函数和constexpr表达式。

问题2

在这种情况下,您只能获得整数上的sin和cos计算的编译时结果,对吗?也就是说,您无法预编译类似sin 45.5这样的结果,对吗?

是和否。在C++03中,您仅限于使用内置函数和模板元函数,constexpr不可用。因此,sin必须是一个模板元函数,只能在整数常量上工作,因为浮点类型在模板中不允许。但是,您可以为分数或定点值定义模板,并为这些值提供sin模板。然而,这将非常繁琐,您可能会遇到模板实例化限制。

自从C++11以来,您可以编写接受浮点参数并使用它们的constexpr函数。


1
要在编译时使用级数展开计算正弦,请参阅http://www10.informatik.uni-erlangen.de/~pflaum/pflaum/ProSeminar/meta-art.html。 - jmihalicza

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接