将set函数(setter)标记为constexpr的目的是什么

What is the purpose of marking the set function (setter) as constexpr?

本文关键字:constexpr 记为 是什么 set 函数 setter      更新时间:2023-10-16

我无法理解将setter函数标记为constexpr的目的,这是从C++14开始允许的。我的误解来自下一种情况:我用constexpr c-tor声明了一个类,并将通过创建该类constexpr Point p1的constexpr实例在constexpr上下文中使用它。对象p1现在是常量,其值无法更改,因此无法调用constexprsetter。另一方面,当我在非constexpr上下文Point p中创建class Point的实例时,我可以调用该对象的setter,但现在setter不会在编译时执行,因为该对象不是constexpr!

因此,我不明白如何使用用于setter的constexpr来提高代码的性能。

这是演示在非constexpr对象上调用constexpr setter的代码,这意味着运行时计算,而不是编译时:

class Point {
public:
constexpr Point(int a, int b)
: x(a), y(b) {}
constexpr int getX() const noexcept { return x; }
constexpr int getY() const noexcept { return y; }
constexpr void setX(int newX) noexcept { x = newX; }
constexpr void setY(int newY) noexcept { y = newY; }
private:
int x;
int y;
};

int main() {
Point p{4, 2};
constexpr Point p1{4, 2};
p.setX(2);
}

有人能帮助我理解将setter函数标记为constexpr的目的吗?

基本上,当您必须处理constexpr函数时,这是很好的。

struct Object {
constexpr void set(int n);
int m_n = 0;
};
constexpr Object function() {
Object a;
a.set(5);
return a;
}
constexpr Object a = function();

其思想是能够在编译时执行的另一个函数中执行编译时初始化。它不会应用于constexpr对象。

需要知道的另一件事是constexpr成员函数不是const成员函数,因为C++14:)。

C++14中的新constexpr规则产生了需求:在constexpr函数中,您现在可以使用多个语句,包括for循环和控制流。

这里有一个例子:

constexpr int count5(int start) {
int acc = 0;
for (int i = start ; i<start+5 ; ++i) {
acc += i;
}
return acc;
}
constexpr int value = count5(10); // value is 60!

正如您所看到的,我们可以在constexpr上下文中对变量进行许多突变。编译器变得像一个解释器,只要constexpr函数的结果是一致的,并且你没有改变已经计算的constexpr变量,它就可能在解释过程中改变值。

带有constexpr限定符的函数将在编译时评估函数的返回,这可以显著提高程序的性能(没有额外的计算,没有指令计数器跳跃等)。这样限定函数有一些要求,请查看IBM的解释。