Compile-Time Evaluation

# constexpr with Recursive Functions

## Can I use constexpr or consteval with recursive functions?

Yes, you can use both constexpr and consteval with recursive functions. This is a powerful feature that allows you to perform complex compile-time computations. Let's explore this with someÂ examples:

## Basic Recursive constexpr Function

Here's a classic example of a recursive factorial function using constexpr. This function will be evaluated at compile-time when used in a constantÂ expression.

#include <iostream>

constexpr int factorial(int n) {
if (n <= 1) return 1;
return n * factorial(n - 1);
}

int main() {
constexpr int result = factorial(5);
std::cout << "5! = " << result;
}
5! = 120

## Recursive consteval Function

You can also use consteval to ensure the function is always evaluated atÂ compile-time:

#include <iostream>

consteval int fibonacci(int n) {
if (n <= 1) return n;
return fibonacci(n - 1) + fibonacci(n - 2);
}

int main() {
constexpr int result = fibonacci(10);
std::cout << "10th Fibonacci number: "
<< result << '\n';
}
10th Fibonacci number: 55

## Compile-Time Limitations

While you can use recursion in constexpr and consteval functions, be aware of compiler limitations. Most compilers have a limit on the depth of constexprÂ recursion:

This might result in a compiler error or warning about exceeding recursionÂ limits.

constexpr long long very_deep_recursion(int n) {
if (n == 0) return 0;
return 1 + very_deep_recursion(n - 1);
}

int main() {
// Might exceed limits
constexpr int result = very_deep_recursion(1000);
}
error: expression did not evaluate to a constant
note: failure was caused by evaluation exceeding call depth limit of 512

## Practical Use Case - Compile-Time String Hashing

Here's a more practical example using recursion to compute a string hash atÂ compile-time:

This recursive function computes the FNV-1a hash of a string at compile-time, which could be useful for switch statements or other compile-time decisions based onÂ strings.

#include <iostream>
#include <string_view>

constexpr uint32_t fnv1a_32(
std::string_view sv, size_t idx = 0) {
constexpr uint32_t FNV_offset_basis = 2166136261U;
constexpr uint32_t FNV_prime = 16777619U;

return idx == sv.size() ? FNV_offset_basis
: (fnv1a_32(sv, idx + 1) ^ sv[idx]) * FNV_prime;
}

int main() {
constexpr auto hash = fnv1a_32("Hello, World!");
std::cout << "Hash of 'Hello, World!': " << hash;
}
Hash of 'Hello, World!': 3644920852

Remember, when using recursion in constexpr or consteval functions, ensure that there's a clear base case to prevent infinite recursion. Also, be mindful of the potential for long compilation times with complex recursiveÂ computations.

Despite these considerations, recursive constexpr and consteval functions are powerful tools for compile-time metaprogramming inÂ C++.

This Question is from the Lesson:

### Compile-Time Evaluation

Learn how to implement functionality at compile-time using constexpr and consteval

Answers to questions are automatically generated and may not have been reviewed.

This Question is from the Lesson:

### Compile-Time Evaluation

Learn how to implement functionality at compile-time using constexpr and consteval

Part of the course:

## Professional C++

Comprehensive course covering advanced concepts, and how to use them on large-scale projects.

Free, unlimited access

### This course includes:

• 124 Lessons
• 550+ Code Samples
• 96% Positive Reviews
• Regularly Updated
• Help and FAQ
Free, Unlimited Access

### Professional C++

Comprehensive course covering advanced concepts, and how to use them on large-scale projects.