Constexpr In C++ - C++ Programming Tutorial
C++ Course / Advanced Topics / Constexpr In C++

Constexpr In C++

BLUF: Mastering Constexpr In C++ is a critical step in becoming a proficient C++ developer. This lesson provides a deep dive into the syntax, performance considerations, and real-world applications of this concept.
Key Performance Insight: Constexpr In C++

C++ is renowned for its efficiency. Learn how Constexpr In C++ enables low-level control and high-performance computing in the tutorial below.

In C++ 11, a functionality known as constexpr was introduced. The core idea revolves around enhancing software efficiency by executing computations during compilation rather than during program execution. It is important to recognize that end-users frequently execute software multiple times post the completion of development and compilation. The aim is to allocate more time during compilation while reducing time during runtime (reminiscent of template metaprogramming). Constexpr signifies that the value of an object or function can be evaluated during compilation and that the expression can be applied in additional constant expressions.

Example

// C++ program to demonstrate constexpr function for product
// of two numbers. By specifying constexpr, we suggest
// compiler to evaluate value at compile time
#include <iostream>
constexpr int product(int x, int y) { return (x * y); }
int main()
{
	constexpr int x = product(10, 20);
	std::cout << x;
	return 0;
}

OUTPUT:

Output

200
.........
Process executed in 1.11 seconds
Press any key to continue.

The const keyword indicates to both programmers and compilers that a variable is meant to be immutable, and any efforts to modify it will result in a compilation error.

In that it denotes a const value, constexpr is comparable to const. Similarly, it remains unchangeable. Const differs in that, based on its initialization method, it can be computed either during compilation or during execution.

Explanation

  • A constexpr function in C++ 11 should only have one return statement. In C++ 14, multiple statements are permitted.
  • Only constant global variables should be used with the constexpr function.
  • Only other constexpr functions, not simple functions, may be called by constexpr functions.
  • The function's type shouldn't be void.
  • Constexpr function prefix increment (++v) was not permitted in C++11; however, this limitation has been lifted in C++14.

Creating a function that simply calculates the product of a specified integer as constexpr may appear insignificant. In what other scenarios could this functionality prove useful beyond improving performance?

  • The primary advantage of this capability is that it allows us to evaluate compile-time constants through a function. By leveraging this, we managed to determine the size of an array during compilation, a task that was previously impossible.
Example

// C++ program to demonstrate constexpr function to evaluate
// the size of array at compile time.
#include <iostream>
constexpr int product(int x, int y) { return (x * y); }
int main()
{
	int arr[product(2, 3)] = {1, 2, 3, 4, 5, 6};
	std::cout << arr[5];
	return 0;
}

OUTPUT:

Output

6
……..
Process executed in 1.11 seconds
Press any key to continue.

Adapting a device from one system to another serves as a practical application. For example, while many individuals prefer working with angles in degrees, trigonometric functions in C/C++ operate with angles in radians. Therefore, we can establish the ConvertDegreeToRadian function as a constexpr, maintaining both code lucidity and performance.

Example

#include <iostream>
using namespace std;
const double PI = 3.14159265359;
constexpr double ConvertDegreeToRadian(const double& dDegree)
{
	return (dDegree * (PI / 180));
}
int main()
{
	auto dAngleInRadian = ConvertDegreeToRadian(90.0);
	cout << "Angle in radian: " << dAngleInRadian;
	return 0;
}

OUTPUT:

Output

Angle in radian: 1.5708
………………………………….
Process executed in 0.11 seconds
Press any key to continue.

Constexpr Vs inline functions

constexpr Inline functions
As the code and expressions are evaluated during compilation, the function calls are removed. It virtually ever eliminates any function calls since it acts on expressions at run time.
The value of the variable or function can be evaluated during compilation. The value of the function or variable cannot be determined at compile time.
It makes no inference about external links. It suggests an external link.

Constexpr performance improvement example:

// An example C++ code showcasing the application of the constexpr keyword

Example

#include<iostream>
constexpr long int fib(int n)
{
	return (n <= 1) ? n : fib(n-1) + fib(n-2);
}
int main ()
{
	// value of res is computed at compile time.
	constexpr long int res = fib(30);
	std::cout << res;
	return 0;
}

OUTPUT:

Output

832040
………….
Process executed in 0.003 seconds
Press any key to continue.

If we remove the const keyword from the following line, the computation of fib(5) will no longer be performed at compile-time because the outcome of the constexpr is not employed in a const expression. This particular code executes successfully on GCC within 0.003 seconds (time measurement can be done using the time command).

Example

Change,
  constexpr long int res = fib(30);  
To,
  long int res = fib(30);

After implementing the mentioned adjustment, the program's runtime extends by 0.017 seconds.

Constructors and constexpr: When constructors are defined with a constexpr specifier, they are known as constexpr constructors. It is possible to instantiate constructors and objects with constexpr as well. The constructor for a constexpr is inherently inline.

Constructor limitations for constexpr usage:

  • lacking a virtual base class
  • Every parameter needs to be literal.
  • The function is not a try-block one.
Example

// C++ program to demonstrate uses
// of constexpr in constructor
#include <iostream>
// A class with constexpr
// constructor and function
class Rectangle
{
	int _h, _w;
public:
	// A constexpr constructor
	constexpr Rectangle(int h, int w) : _h(h), _w(w) {}
	
	constexpr int getArea() { return _h * _w; }
};
// driver program to test function
int main()
{
	// Below object is initialized at compile time
	constexpr Rectangle obj(10, 20);
	std::cout << obj.getArea();
	return 0;
}

OUTPUT:

Output

200
……..
Process executed in 0.17 seconds
Press any key to continue.

Constexpr Vs const

They serve diverse purposes. The const keyword is ideal for defining constants such as the value of Pi, while constexpr is mainly utilized for enhancing performance. Member functions have the flexibility to employ either of these keywords. By marking member functions as const, inadvertent alterations to the function are avoided. In contrast, constexpr is designed to evaluate expressions during compile time, optimizing the code execution process. The constexpr specifier is applicable to both member and non-member functions, including constructors, whereas const is restricted to non-static member functions. It is essential to note that both const and constexpr necessitate that the argument and return types are literal types.

Input Required

This code uses input(). Please provide values below:

Logic Practice
Install Logic Practice
Add to home screen for a faster app-like experience