MareArts ANPR mobile app

12/12/2025

c++ constexpr #02_constexpr_functions.cpp

 

..

// Example 2: Understanding constexpr/consteval Functions
// These functions run at COMPILE TIME and return results the compiler can use

#include <iostream>

// ==========================================
// CONSTEXPR: Function evaluated at compile time
// ==========================================

// Regular function - runs at runtime
bool isDogRuntime(const char* type) {
return type[0] == 'D'; // Check if starts with 'D'
}

// Constexpr function - can run at compile time!
constexpr bool isDogCompileTime(const char* type) {
return type[0] == 'D';
}

// Consteval (C++20) - MUST run at compile time
consteval bool isDogMustCompileTime(const char* type) {
return type[0] == 'D';
}

// ==========================================
// Animal types
// ==========================================

struct Dog {
static constexpr const char* type = "marearts.com Dog";
};

struct Cat {
static constexpr const char* type = "marearts.com Cat";
};

struct Bird {
static constexpr const char* type = "marearts.com Bird";
};

// ==========================================
// Using constexpr functions with "if constexpr"
// ==========================================

template <typename T>
void describeAnimal() {
// if constexpr - evaluated at COMPILE TIME
if constexpr (isDogCompileTime(T::type)) {
std::cout << "This is a DOG - has 4 legs, barks\n";
}
else if constexpr (T::type[0] == 'C') { // Can use any compile-time expression
std::cout << "This is a CAT - has 4 legs, meows\n";
}
else {
std::cout << "This is a BIRD - has 2 legs, flies\n";
}
}

// ==========================================
// Difference: regular if vs if constexpr
// ==========================================

template <typename T>
void regularIf() {
// Regular if - runs at RUNTIME, all branches must be valid
if (isDogRuntime(T::type)) {
std::cout << "Runtime check: Dog\n";
}
}

template <typename T>
void constexprIf() {
// if constexpr - evaluated at COMPILE TIME, only chosen branch exists
if constexpr (isDogCompileTime(T::type)) {
std::cout << "Compile-time check: Dog\n";
}
}

// ==========================================
// Main
// ==========================================

int main() {
std::cout << "=== Using constexpr functions with 'if constexpr' ===\n\n";
describeAnimal<Dog>();
describeAnimal<Cat>();
describeAnimal<Bird>();
std::cout << "\n=== Difference between regular if and if constexpr ===\n\n";
regularIf<Dog>();
constexprIf<Dog>();
// With constexpr, the check happens at COMPILE TIME!
// The compiler removes the unused branches - they don't even exist in final code!
return 0;
}

/*
KEY POINTS:
1. constexpr/consteval functions run at COMPILE TIME
2. "if constexpr" uses compile-time checks
3. Only the chosen branch exists in final code (very efficient!)
4. Can't use constexpr functions in "requires" clauses - they need concepts
5. But CAN use constexpr functions in "if constexpr" - that's the dispatcher pattern!
*/


..

------------------------------------------------------------

How to build

> g++ -std=c++20 02_constexpr_functions.cpp -o 02_constexpr_functions

>./02_constexpr

=== Using constexpr functions with 'if constexpr' ===

This is a DOG - has 4 legs, barks

This is a CAT - has 4 legs, meows

This is a BIRD - has 2 legs, flies

=== Difference between regular if and if constexpr ===

Runtime check: Dog

Compile-time check: Dog

------------------------------------------------------------------------------------------------------------------------


### 2. Constexpr Functions (02_constexpr_functions.cpp)
**What it teaches:** Functions that run at compile time

```cpp
// Constexpr function - evaluated at compile time
constexpr bool isDog(const char* type) {
return type[0] == 'D';
}

// Use in if constexpr
template <typename T>
void describe() {
if constexpr (isDog(T::type)) { // ✅ Function works here!
std::cout << "It's a dog!";
}
}
```


OK then what is different constexpr and consteval and anything else? 

1. constexpr (C++11)

Can run at compile time OR runtime, depending on context:
02_constexpr_functions.cppLines 15-18
Flexible: The compiler decides when to evaluate it.

2. consteval (C++20)

MUST run at compile time - stricter than constexpr:
02_constexpr_functions.cppLines 20-23
Strict: Compile error if it can't be evaluated at compile time.

3. constinit (C++20)

Ensures variables are initialized at compile time (doesn't apply to functions):

Bonusif constexpr (C++17)

Not a function specifier, but a compile-time conditional statement:
02_constexpr_functions.cppLines 47-57

Quick Comparison

So the answer isthree main keywords (constexprconstevalconstinit), plus if constexpr for compile-time conditionals! 🎯


ok, one thing to clear 

Both are equivalent:

The only requirement for if constexpr is that the condition must be a compile-time constant expression - it doesn't matter whether it comes from a function call or is written inline🎯


What is meaning constexpr is flexible??

constexpr - Flexible (Can do both)

02_constexpr_functions.cppLines 15-18
This same function can be used in BOTH ways:

✅ Use 1: Compile-time evaluation

✅ Use 2: Runtime evaluation

consteval - NOT Flexible (Compile time only)

02_constexpr_functions.cppLines 20-23
This can ONLY be used at compile time:

Summary

"Flexible" = The compiler decides when to evaluate it based on context! 🎯


One more thing to clear!! what happened in runtime exactly?

When you call a constexpr function with runtime values, it simply executes as a regular function during program execution.

Here's what happens:

Think of constexpr like this:

Visual Timeline:

Compile Time (if arguments are constants):
Runtime (if arguments are not constants):
So yesconstexpr with runtime values = normal function execution! 🎯


That's it.

Thank you!


Study.marearts.com!!!




No comments:

Post a Comment