C++ Constexpr and Consteval
constexpr and consteval mark functions that can run while a program is being built. A consteval function must run at that time, while a constexpr function may also run later.
A constexpr result sizes a fixed array
The tableSize function multiplies its rows by four. Its result sizes the array, and the loop fills and prints the array.
#include <iostream>
constexpr int tableSize(int rows) {
return rows * 4;
}
int main() {
int table[tableSize(2)];
for (int i = 0; i < tableSize(2); i++) {
table[i] = (i + 1) * 10;
}
for (int i = 0; i < tableSize(2); i++) {
if (i > 0) {
std::cout << " ";
}
std::cout << table[i];
}
std::cout << std::endl;
return 0;
}The same function with a runtime value
The rows value is set inside main and read while the program runs. The same tableSize function still works and returns its product.
#include <iostream>
constexpr int tableSize(int rows) {
return rows * 4;
}
int main() {
int rows = 3;
int size = tableSize(rows);
std::cout << "Size: " << size << std::endl;
return 0;
}A consteval function called with a literal
The cube function is marked consteval. The call passes the literal 3, so the value 27 is worked out while the program is built.
#include <iostream>
consteval int cube(int n) {
return n * n * n;
}
int main() {
int value = cube(3);
std::cout << value << std::endl;
return 0;
}A consteval call with a runtime value fails
The side value is set while the program runs. The consteval call refuses it, and the output shows the real refusal line.
#include <iostream>
consteval int cube(int n) {
return n * n * n;
}
int main() {
int side = 3;
int value = cube(side);
std::cout << value << std::endl;
return 0;
}if constexpr with a bool template parameter
The report function takes a bool template parameter named Verbose. The true call prints the extra line and the false call skips it.
#include <iostream>
template <bool Verbose>
void report(int value) {
std::cout << "Value: " << value << std::endl;
if constexpr (Verbose) {
std::cout << "Extra detail" << std::endl;
}
}
int main() {
report<true>(7);
report<false>(8);
return 0;
}Example
#include <iostream>
constexpr int price(int units) {
return units * 15;
}
int main() {
int prices[4];
for (int i = 0; i < 4; i++) {
prices[i] = price(i + 1);
}
for (int i = 0; i < 4; i++) {
if (i > 0) {
std::cout << " ";
}
std::cout << prices[i];
}
std::cout << std::endl;
return 0;
}Key points
- constexpr marks a function that can run while the program is being built.
- A constexpr result can size a fixed array.
- A constexpr function can also run later with a value known only then.
- consteval marks a function that must run while the program is being built.
- A consteval call needs values known at build time.
- if constexpr picks a branch while the program is being built.
- The branch that is not picked is left out of the built program.
In this example, price returns units times 15 for each count from one to four. The loop stores 15, 30, 45, and 60 in the array. The second loop prints the four stored prices in one row.
Note
constexpr means a function can run at build time. It does not force every call to run then.
Try it Yourself
Edit the code, then press Run.
Running is simulated
Exercise
What happens when a consteval function is called with a value set while the program runs?