constexpr与纯函数之间的关系

Umm*_*mma 19 c++ constexpr c++11

我是对的,那个:

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

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

Jam*_*lis 17

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

template <typename T>
constexpr T add(T x, T y) { return x + y; }
Run Code Online (Sandbox Code Playgroud)

constexpr功能模板是在某些情况下,一个常量表达式(例如,其中可用Tint),但不是在其他人(例如,其中T是用一个类类型operator+未声明过载constexpr).

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

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


Jam*_*nze 9

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

  • @James:原则上,你可以用递归来表达每个循环,并且可以使用函数参数"保存"状态,因此`constexpr`函数的集合是turing完成的.另见http://en.wikipedia.org/wiki/Church-Turing_thesis.作为一个有趣的注释,请查看http://gitorious.org/metatrace,一个完整的编译时光线跟踪器,其中还包括平方根计算和光线/球体和光线/平面交叉计算.但是,sin/cos并没有受到伤害. (6认同)
  • 我认为这样的事情是有效的:"constexpr int fact(int n){return(n!= 0?fact(n - 1)*n:1);}"所以虽然实现sqrt()可能很棘手sin()就constexpr而言,我认为这当然是可能的. (3认同)

Mat*_* M. 7

constexpr功能都没有pure,因为constexpr是一个提示,该函数可以在编译期间被计算编译器,如果它的参数是常数操作在函数体mentionned,对于这些参数,本身constexpr.

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

template <typename T>
constexpr T add(T lhs, T rhs) { return lhs + rhs; }
Run Code Online (Sandbox Code Playgroud)

用这种类型实例化

DebugInteger operator+(DebugInteger lhs, DebugInteger rhs) {
  printf("operator+ %i %i", lhs._value, rhs._value);
  return DebugInteger(lhs._value + rhs._value);
}
Run Code Online (Sandbox Code Playgroud)

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

我们可以说constexpr函数是pure在编译时进行评估的......但是就运行时而言,它只是被一个常量所取代.

  • 模板函数实际上是一系列函数,在您的示例中,任何不纯的家族成员也必然不是constexpr. (2认同)