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
?
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:
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.
A function with
constexpr
qualifier will evaluate the return of the function at compile time, which can significantly boost performance of a program (no extra computation, no instruction counter jumping, etc.). There are a few requirements to qualify a function thusly, so check out this explanation from IBM.Basically it is nice when you have to deal with constexpr 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 notconst
member functions since C++14 :).