繁体   English   中英

constexpr与纯函数之间的关系

[英]Relation between constexpr and pure functions

我是对的,那个:

  • 使用constexpr定义的任何函数都是纯函数 ,并且
  • 如果编译器的价格不是很高,那么任何纯函数都可以并且必须用constexpr定义。

如果是这样,为什么用constexpr定义<cmath>的函数?

要添加其他人所说的内容,请考虑以下constexpr功能模板:

template <typename T>
constexpr T add(T x, T y) { return x + y; }

constexpr函数模板在某些情况下可用于常量表达式(例如,其中Tint )但在其他情况下不可用(例如,其中T是具有未声明为constexproperator+重载的类类型)。

constexpr并不意味着该函数始终可用于常量表达式,这意味着该函数用于常量表达式。

(有类似的例子涉及非模板函数。)

除了之前的答案之外:函数上的constexpr极大地限制了它的实现:它的主体必须对编译器可见(内联),并且必须只包含一个return语句。 如果你能正确实现sqrt()或sin()并仍然满足最后一个条件,我会感到惊讶。

constexpr函数pure因为constexpr是编译器的一个提示, 如果函数的参数是常量 那么在编译期间可以计算函数,并且函数体中提到的操作对于这些参数本身就是constexpr

后者使用模板代码,允许我们演示一个不纯的constexpr函数:

template <typename T>
constexpr T add(T lhs, T rhs) { return lhs + rhs; }

用这种类型实例化

DebugInteger operator+(DebugInteger lhs, DebugInteger rhs) {
  printf("operator+ %i %i", lhs._value, rhs._value);
  return DebugInteger(lhs._value + rhs._value);
}

这里, operator+不是constexpr,因此可以读/写全局状态。

我们可以说constexpr函数在编译时进行评估是pure ......但就运行时而言,它只是被常量替换。

每个constexpr函数都是纯粹的,但不是每个纯函数都可以或应该是constexpr

[涉及constexpr函数模板的示例具有误导性,因为函数模板不是函数,它们是编译器可以生成函数的模式。 功能模板的结果,它们的专业化, 功能,如果可能,它们constexpr 。]

纯函数是仅依赖于其参数或其他常量状态的函数。 这几乎是一个constexpr功能。 此外, constexpr函数必须在第一次使用之前定义(不仅声明)(但似乎允许递归),并且必须仅包含return语句。 这足以使允许的子集Turing-complete,但结果不一定是运行时最有效的形式。

这带给我们数学函数。 您可以实现constexpr sqrt()sin() ,但是它们必须使用编译器可以在编译时评估的递归实现,而在运行时,这些将在一个汇编器操作中更好地实现。 由于constexpr使用的sqrt()sin()很少,而且相距甚远,它能够更好地最大化的运行时性能相反,它要求的是不是一个形式constexpr能。

你可能想知道为什么你不能写一个constexpr版本的函数和一个在运行时使用的版本,我同意这样做很好,但是标准说你不能在constexpr过载。 也许在C ++ 17 ...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM