C++

C++ Constexpr String Examples

This article will discuss about constexpr, a notable addition to the C++ programming language that is introduced in C++11 and enhanced further in C++14, and signals to the compiler that a variable, function, or object constructor is a compile-time constant. It revolutionized the way the developers create and manipulate the constants. Through constexpr, the developers can define the expressions and values that are immutable and evaluated during the compilation rather than at runtime. The overarching benefit of incorporating constexpr into the code is its guarantee of constancy.

What Is the Use of the C++ Constexpr String?

Utilizing constexpr can lead to more compact and optimized executable files. Since the values are determined in advance by the compiler, the resulting binaries can be smaller in size, realizing a more economical use of system resources which in turn can enhance the performance of the software on various platforms. One special significant advantage of this feature is the reduction it brings to the runtime computations. As values are calculated during the compilation process whenever feasible, the runtime evaluation becomes less necessary. This efficiency boost not only accelerates the execution but also streamlines the overall program operations.

Example 1: Using Constexpr in C++ for Factorial Calculation

In this example, we’ll use constexpr which allows the computations to be performed at compile-time rather than at run-time. In the context of calculating factorials, a common mathematical operation, which is constexpr, can be leveraged to compute factorial values during compilation. Let’s examine and review the following code and then look at the explanation of the code:

#include <iostream>

constexpr int factorial(int n) {

  return n <= 1 ? 1 : (n * factorial(n - 1));

}

int main() {

  int num = 5;

  std::cout << "Factorial of " << num << " = " << factorial(num) << std::endl;

}

The given code example demonstrates the use of constexpr for calculating the factorial of a number in a recursive way. The compiler is able to evaluate the factorial expression at compile-time in this example because the factorial function is declared and defined with the constexpr specifier. Using constexpr in a C++ program, the compiler evaluates the factorial expression of 5 at compile-time, eliminating the need for runtime computation.

Now, let us see the detailed breakdown of the code with specific details and explanations.

First, we use the #include <iostream> to incorporate the “iostream” header file which provides essential input and output functionalities like “std::cout” for printing to the console.

Afterward, we move into the factorial() function (recursive) which is “constexpr int factorial(int n)”. This factorial() function defines a recursive function that calculates the factorial of an “n” integer. Constexpr implies that performance optimizations can result from evaluating the function during compilation.

The return n <= 1 ? 1 : (n * factorial(n – 1)) line employs a conditional expression for recursion which states that if “n” is less than or equal to 1, it returns 1 (base case). If not, it does the factorial computation (n! = n * (n-1)!), which is the general formula for computing the factorial, by repeatedly calling itself with “n – 1” and then multiplying the result by “n”. These lines act like a gatekeeper for factorial calculation. It checks if the number is at the base level and returns 1 if so. If not, it kicks off a chain reaction of function calls, each working on smaller numbers until the base case is reached. Then, the results are multiplied together in reverse order. The following is the output of the code for your reference:

Example 2: Counting the Lowercase Letters Demonstrating the C++ Constexpr String

Here, we will learn how to count the number of lowercase letters using a countexpr string. In this example, the purpose is to count the number of lowercase letters in a given string using the constexpr feature to reduce the runtime computation. The countLowercase() function, declared as constexpr, takes a “string_view” string as its parameter and iterates through each character of the given string as input. For every lowercase letter that we encounter, the count is incremented. The result is then obtained at compile time as the function operates on constant expressions, showcasing the compile-time evaluation’s efficiency and performance benefits. First, check the following code. Then, move on to the detailed explanation:

#include <iostream>
#include <string_view>
using namespace std;
constexpr size_t countLowercase (string_view s) {
    size_t count = 0;
    for (char c : s) {
        if (islower(c)) {
            count++;
        }
    }
    return count;
}
int main() {
    cout << "Total lowercase letters in "LoWeR CaSe LeTtErS" are = "
              << countLowercase ("LoWeR CaSe LeTtErS") << endl;
}

Here’s a detailed breakdown of the code with an explanation of each line:

The #include <iostream> is included to use the standard input/output stream library to print the messages. The #include <string_view> includes the “string_view” class for efficient string manipulation.

In the countLowercase() function, the “constexpr size_t countlower(string_view s)” function, counts the lowercase letters in a given string view. The int main() is the program’s entry point that prints a message that indicates the number of lowercase letters in “LoWeR CaSe LeTtErS” and calls the countLowercase() function with “LoWeR CaSe LeTtErS” as input and prints the result. Refer to the following output of the program:

Example 3: Array Demonstration by Utilizing the C++ Constexpr

An array demonstration shows how the arrays that are structured collections of elements of the same data type are created, accessed, and manipulated within a programming language. In the following, we will explain through a coding example in which the program provides a simple example of compile-time array initialization and manipulation.

An array demonstration illustrates the concept of arrays—a structured collection of elements that share the same data type—and how they can be created, accessed, and manipulated using a programming language. In the following coding example, we will demonstrate how to initialize an array at compile-time, calculate its size, and print the elements of the given array. See the following given code and proceed to the explanation:

#include <iostream>
using namespace std;
int main() {
    constexpr int arrayint[9] = {5, 55, 555, 5555, 55555};
    constexpr int size_array = sizeof arrayint / sizeof(int);
    cout << "The Array's length is = " << size_array<<endl;
    cout << "The elements in array are = ";
    for (int i = 0; i < size_array; ++i) {
        cout << arrayint[i] << ' ';
    }
}

This program initializes a constexpr array, calculates its length at compile time, and then prints the array’s length and elements to the console. Constexpr ensures that the array and its properties are determined at compile time. Let’s break the code and explain the specific details one by one:

To include the standard input-output stream library, allowing the use of functions like “cout” for output, #include <iostream> is called. The program begins the execution from the int main() function. Within the main() function, the “arrayint[]” array is defined, having a size of 9 with a constexpr int arrayint[9] statement. The array is initialized with five numbers, and the remaining elements implicitly remained 0. The int length_a = sizeof arrayint / sizeof(int); calculates the size of the “arrayint” in bytes.

A “for” loop iterates through the elements of the “arrayint[]”array, and the values are then printed to the console. Let us see the following output of the given code:

Conclusion

The introduction and evolution of the constexpr keyword in C++ have revolutionized how constant expressions and values are handled. This article explored three practical examples, showcasing the power of constexpr in computing factorials, counting the lowercase letters, and initializing the arrays at compile time. The key takeaways include enhanced performance, reduced runtime calculations, and improved memory efficiency. Constexpr is a valuable asset for creating reliable, constant entities within a codebase, ensuring immutability and contributing to more streamlined and efficient programs.

About the author

Kalsoom Bibi

Hello, I am a freelance writer and usually write for Linux and other technology related content