6

看到 Todd Veldhuizen 的元编程指南中的最后一个示例给我留下了深刻的印象,其中 trig 函数类似于sincos在编译时预先计算。老实说,这让我大吃一惊,如果您编写的代码像我一样在循环中执行大量此类操作,那么这可能会对提高性能产生重大影响。

问题 1

然而,这让我想知道在什么可用作运行时工具(调用实际的数学库函数,如sinor cos)与仅可用作编译时数学运算符之间的界限在哪里。

Todd 的示例需要仅使用普通算术手动计算三角函数。

我是否应该假设编译器能够处理所有普通的数学函数* + - /,但没有别的?

问题2

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

或者,如果模板只能接受整数作为参数,您可以在类中获取多个整数并将它们组合float在一起,例如传递1 2 3和制作浮点值。1.23sin

4

1 回答 1

2

问题 1

然而,这让我想知道在什么可用作运行时工具(调用实际的数学库函数,如 sin 或 cos)和什么可用作编译时数学运算符之间划清界限。

  • 命名函数只能在编译时使用,前提是它们已声明constexpr、遵守规则constexpr并使用编译时常量调用。
  • 用户定义的数据类型只能在编译时使用,前提是它们是通过constexpr编译时常量的构造函数构造的。
  • 任何对编译时常量内置类型进行操作的内置运算符都会给出编译时常量。
  • 如果原始是编译时常量,则内置函数之间的任何类型转换都会给出编译时常量。

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

问题2

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

是和不是。在 C++03 中,您仅限于内置函数和模板元函数,constexpr不可用。因此sin,必须是一个模板元函数,它只能在整数常量上工作,因为模板中不允许浮点类型。但是,您可以为分数或定点值定义模板,并sin为它们提供一个模板。不过,这将非常乏味,并且您很容易最终遇到模板实例化的限制。

从 C++11 开始,您可以编写constexpr带有浮点参数的函数并使用这些函数。

于 2013-05-27T06:20:14.470 回答