You must have read the post about const pointer and pointer to const or you can learn after this also.
const (run time)
- It is part of data type declaration.
- It establishes that initially assigned value can't be changed.
- It is like an agreement that the code which is under const will not change the data.
- Can't be evaluated at compile time rather run-time. But, C++98 const int will be evaluated at compile time.
Eg1: const int var1 = 5; // will be evaluated at compile-time
With C++11 and later, a top level const on a return value disables move semantics which can lead to otherwise needless copying, so the new rule with C++11 and later is 'almost never use const on return type'.
That's an important exception to the general rule of using const almost everywhere.
#include <iostream> #include <memory> int main() { const int var1 = 5; const double var2 = 8.4; std::cout << "var1 " << var1 << " var2 " << var2 <<std::endl; constexpr int var3 = var1 + 3; constexpr double var4 = var2 + 3.5; std::cout << "var3 " << var3 << " var4 " << var4 <<std::endl; return 1; }
constexpr (compile-time)
- It is not part of data type declaration unlike const, so it can appear only once in the declaration.
- It is similar to static and inline keywords. So, It acts as a modifier to the entire declaration.
- It is a new C++11 keyword that rids you of the need to create macros and hardcoded literals.
- It also guarantees, under certain conditions, that objects undergo static initialization. It controls the evaluation time of an expression. By enforcing compile-time evaluation of its expression,
constexpr
lets you define true constant expressions that are crucial for time-critical applications, system programming, templates, and generally speaking, in any code that relies on compile-time constants. It is not a rule and not necessary to evaluate the code at compile-time.
- Two constexpr on a single expression is not possible, but const is possible.
#include <iostream> using namespace std; constexpr int fac(constexpr int n) { return n == 1 ? 1 : n * fac(n - 1); } int main() { constexpr int f5 = fac(5); cout << "The value of f5 is " << f5 << endl; }
main.cpp:5:19: error: a parameter cannot be declared ‘constexpr’
5 | constexpr int fac(constexpr int n) |
- This mostly accompanied by static keyword for class members.
static constexpr double PI = 3.1415926;
- A function or variable both can be specified as constexpr. constexpr function can be called by another constexpr function and not simple function. The return value of constexpr function can be assigned to another const variable.
- The return value of constexpr function is constant and computed at compile time.
- prefix increment is not allowed.
Advantages
- It is mainly used for performance improvement. The expressions are evaluated at compile time. - this is the main reason for using constexpr. When a value is computed at compile time, it helps your program to run faster and use less memory.
#include <iostream> using namespace std; // Pass by value constexpr float exp(float x, int n) { return n == 0 ? 1 : n % 2 == 0 ? exp(x * x, n / 2) : exp(x * x, (n - 1) / 2) * x; } // Pass by reference constexpr float exp2(const float& x, const int& n) { return n == 0 ? 1 : n % 2 == 0 ? exp2(x * x, n / 2) : exp2(x * x, (n - 1) / 2) * x; } // Compile-time computation of array length template<typename T, int N> constexpr int length(const T(&)[N]) { return N; } // Recursive constexpr function constexpr int fac(int n) { return n == 1 ? 1 : n * fac(n - 1); } // User-defined type class Foo { public: constexpr explicit Foo(int i) : _i(i) {} constexpr int GetValue() const { return _i; } private: int _i; }; int main() { // foo is const: constexpr Foo foo(5); // Compile time: constexpr float x = exp(5, 3); constexpr float y { exp(2, 5) }; constexpr int val = foo.GetValue(); constexpr int f5 = fac(5); const int nums[] { 1, 2, 3, 4 }; const int nums2[length(nums) * 2] { 1, 2, 3, 4, 5, 6, 7, 8 }; // Run time: cout << "The value of foo is " << foo.GetValue() << endl; }
The value of foo is 5
Click here to debug
The difference between const and constexpr
1. Initialisation of const can deferred until run time whereas the constexpr must be initialised at compile time.
Why constexpr is static?
constexpr in class context refer to instance or class member or function, so compiler can't determine if it's static or not, ie bound or not to specific instance. It's same reasoning as const specifier.
Reference
why constexpr is not non-static?
Comments
Post a Comment