[英]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
函数模板在某些情况下可用于常量表达式(例如,其中T
为int
)但在其他情况下不可用(例如,其中T
是具有未声明为constexpr
的operator+
重载的类类型)。
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.