【问题标题】:What is the purpose of marking the set function (setter) as constexpr? [duplicate]将 set 函数(setter)标记为 constexpr 的目的是什么? [复制]
【发布时间】:2019-02-07 14:20:45
【问题描述】:

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

因此,我不明白如何将 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);
}

谁能帮我理解将setter函数标记为constexpr的目的是什么?

【问题讨论】:

  • constexpr 说明符声明可以在编译时计算函数或变量的值。简单明了。就像你写了Point p2{2, 2} 并在后续语句中使用它而不是 p。

标签: c++ c++14 constexpr


【解决方案1】:

基本上,当您必须处理 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 :)。

【讨论】:

    【解决方案2】:

    在 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 变量,它可能会在解释过程中改变值。

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-12-17
        • 1970-01-01
        • 2022-09-23
        • 1970-01-01
        • 1970-01-01
        • 2022-11-17
        • 2011-07-03
        • 1970-01-01
        相关资源
        最近更新 更多