将设置函数(设置器)标记为constexpr的目的是什么?

时间:2019-02-07 14:20:45

标签: c++ c++14 constexpr

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

结果,我不明白如何使用constexpr的setter来增强代码的性能。

这是演示在非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);
}

有人可以帮助我了解将设置器功能标记为constexpr的目的是什么吗?

3 个答案:

答案 0 :(得分:15)

基本上,当您需要处理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成员函数不是C ++ 14以来的const成员函数:

答案 1 :(得分:6)

使用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变量进行变异,它就可能在解释过程中使值变异。

答案 2 :(得分:-1)

带有constexpr限定符的函数将在编译时评估函数的返回结果,这可以显着提高程序的性能(无需额外的计算,无需跳转指令计数器等)。 )。因此,有一些要求限定功能的要求,因此请查看IBM的说明。