Learn How To Use constexpr In Modern C++ With C++Builder For Windows Development
In this tutorial, you will learn how to utilize constexpr variables and constexpr functions. The principal idea is the performance enhancement of applications by doing calculations at compile time rather than run time. The purpose is to allocate time in the compilation and save time and run time.
The constexpr keyword was introduced in C++11 and improved in C++14 and C++17. constexpr specifies that the value of an object or a function can be evaluated at compile-time and the expression can be used in other constant expressions. A compiler error is raised when any code tries to alter the value. Unlike const, constexpr can also be applied to functions and class constructors. constexpr symbolizes that the value or return value is constant and where possible is calculated at compile time.
The primary difference between const and constexpr variables is that the initialization of a const variable can be deferred until run time. A constexpr variable must be initialized at compile time. Moreover, all declarations of a constexpr variable or function must have the constexpr specifier.
constexpr float x = 42.0; constexpr float y{108}; constexpr float z = exp(5, 3); constexpr int i; // Error! Not initialized int j = 0; constexpr int k = j + 1; //Error! j not a constant expression |
With C++17, we can estimate conditional expressions at compile time. The compiler is then able to eliminate the false branch.
templatetypename T> auto get_value(T t) { if constexpr (std::is_pointer_vT>) { return *t; } else { return t; } } |
You can do more amazing things with if constexpr. Be sure to check out these workshops:
constexpr Functions
A constexpr function is one whose return value is computable at compile time when consuming code requires it. A constexpr function or constructor is implicitly inline.
constexpr int method_call(int a, int b) { return a * b; } |
Example
The following sample shows constexpr variables, functions and several use cases
#include
#include
#include
constexpr int method_call(int a, int b) {
return a * b;
}
constexpr auto degrees_to_radians(const double degrees) {
return degrees * (M_PI / 180.0);
}
constexpr int sum(int n) {
if (n > 0) {
return n + sum(n – 1);
}
return n;
}
template
auto get_value(T t) {
if constexpr (std::is_pointer_v
return *t;
} else {
return t;
}
}
int _tmain(int argc, _TCHAR* argv[]) {
constexpr int i = 1 + 2;
constexpr int j = method_call(5, 10);
constexpr auto radians = degrees_to_radians(90);
constexpr auto sum_one_to_ten = sum(10);
int a = 5;
int* pa = &a;
int at = 5;
int* pt = &at;
auto value_a = get_value(a);
auto value_pa = get_value(pa);
std::cout
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
#ifdef _WIN32 #include #else typedef char _TCHAR; #define _tmain main #endif
#include #include #include
constexpr int method_call(int a, int b) { return a * b; }
constexpr auto degrees_to_radians(const double degrees) { return degrees * (M_PI / 180.0); }
constexpr int sum(int n) { if (n > 0) { return n + sum(n – 1); }
return n; }
templatetypename T> auto get_value(T t) { if constexpr (std::is_pointer_vT>) { return *t; } else { return t; } }
int _tmain(int argc, _TCHAR* argv[]) { constexpr int i = 1 + 2; constexpr int j = method_call(5, 10);
constexpr auto radians = degrees_to_radians(90); constexpr auto sum_one_to_ten = sum(10);
int a = 5; int* pa = &a; int at = 5; int* pt = &at;
auto value_a = get_value(a); auto value_pa = get_value(pa);
std::cout value_a std::endl; std::cout value_pa std::endl;
system(“pause”); return 0; } |
Be sure to check out more modern C++ samples on this repository!