Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I cannot understand the purpose of marking the setter function as constexpr, that is allowed since C++14. My misunderstanding comes from the next situation: I declare a class with a constexpr c-tor, and I am about to use it in a constexpr context, by creating a constexpr instance of that class constexpr Point p1. An object p1 now is constant and its value could not be changed, so the constexpr setter could not be called. On the other hand, when I create an instance of my class Point in a non-constexpr context Point p, I can call the setter for that object, but now setter will not execute at compile-time, because the object is not constexpr!

As a result, I do not understand how can I enhance the performance of my code using constexpr for setters.

This is the code that demonstrates calling a constexpr setter on an non-constexpr object, that means run-time computation, instead of the compile-time:

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);
}

Could anyone help me to understand what is the purpose of marking the setter function as constexpr?

like image 712
mariia_kornieva Avatar asked Feb 07 '19 14:02

mariia_kornieva


People also ask

What is the point of constexpr functions?

constexpr functions A constexpr function is one whose return value is computable at compile time when consuming code requires it. Consuming code requires the return value at compile time to initialize a constexpr variable, or to provide a non-type template argument.

What is a constexpr variable?

constexpr stands for constant expression and is used to specify that a variable or function can be used in a constant expression, an expression that can be evaluated at compile time. The key point of constexpr is that it can be executed at compile time. Your code may have been executed before you run it.

Why does constexpr need to be static?

A static constexpr variable has to be set at compilation, because its lifetime is the the whole program. Without the static keyword, the compiler isn't bound to set the value at compilation, and could decide to set it later.


Video Answer


2 Answers

Basically it is nice when you have to deal with constexpr function.

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();

The idea is to be able to perform compile time initialization within another functions that will be executed at the compile time. It is not done to be applied on constexpr object.

Another things to know is that constexpr member functions are not const member functions since C++14 :).

like image 78
Antoine Morrier Avatar answered Sep 28 '22 14:09

Antoine Morrier


The need arise with new constexpr rule with C++14: inside constexpr function, you can now use multiple statements, including for loops and control flow.

Here's an example:

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!

As you can see, we can do many mutation to variable in a constexpr context. The compiler becomes like an interpreter, and as long as the result of the constexpr fonction is consistent and you don't mutate already computed constexpr variables, it may mutate the values during the interpretation.

like image 38
Guillaume Racicot Avatar answered Sep 28 '22 14:09

Guillaume Racicot