C++ constexpr - 可以在编译时评估值吗?

Apo*_*ica 6 c++ c++11

我在constexpr 这里读到:

constexpr指定符,它可以评估在编译时函数或变量的值.

当我第一次阅读这句话时,它对我来说非常有意义.但是,最近我遇到了一些完全让我失望的代码.我重建了一个简单的例子如下:

#include <iostream>

void MysteryFunction(int *p);

constexpr int PlusOne(int input) {
  return input + 1;
}

int main() {
  int i = 0;
  MysteryFunction(&i);
  std::cout << PlusOne(i) << std::endl;

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

看看这段代码,我无法说出PlusOne(i)应该是什么结果,但它实际上是编译的!(当然链接会失败,但g++ -std=c++11 -c成功没有错误.)

什么是"可以在编译时评估函数值的正确解释"?

Bri*_*ian 11

如果满足常量表达式的评估的其他要求,可以在常量表达式内调用constexpr函数.它也可以不是恒定的表达的表达,在这种情况下,它的行为一样,如果它没有被宣布与内调用.正如您的问题中的代码所示,调用函数的结果不会自动成为常量表达式.constexprconstexpr


Lig*_*ica 8

从某种意义上说,引用的措辞有点误导.如果您只是PlusOne孤立并观察其逻辑,并假设输入在编译时是已知的,那么其中的计算也可以在编译时执行.拍打constexpr关键字确保我们保持这种可爱的状态,一切都很好.

但是如果输入在编译时未知的,那么它仍然只是一个普通函数,并将在运行时调用.

因此,在这种特定情况下constexpr,函数的属性("可以在编译时评估某些输入而不是所有输入)"而不是函数/输入组合(因此也不适用于此特定输入).

这是一个有点像功能如何能够采取const int&,但并不意味着原来的对象必须const.在这里,类似地,constexpr在函数上添加约束,而不在函数的输入上添加约束.

不可否认,这一切都是一个巨大的,混乱的,模糊不清的混乱(C++!耶!).请记住,您的代码描述了程序的含义!在编译的不同阶段,它不是机器指令的直接配方.

(要真正强制执行此操作,您必须将整数作为模板参数.)


R S*_*ahu 7

什么是"可以在编译时评估函数值的正确解释"?

如果函数的所有参数在编译时都是可评估的,那么可以在编译时计算函数的返回值.

但是,如果仅在运行时知道函数的参数值,则只能在运行时计算函数的重新调整值.

因此,可以在编译时评估函数的值,但这不是必需的.