C++ constexpr Function | 'Compile-Time Function' Guide
이 글의 핵심
constexpr int square(int x) { return x * x; }.
What is constexpr Function?
Function usable at both compile-time and runtime
constexpr int square(int x) {
return x * x;
}
int main() {
// Compile-time
constexpr int a = square(5); // 25 (calculated at compile time)
// Runtime
int x = 10;
int b = square(x); // Runtime calculation
}
C++11 vs C++14 vs C++17
// C++11: Single return statement only
constexpr int factorial11(int n) {
return n <= 1 ? 1 : n * factorial11(n - 1);
}
// C++14: Like regular functions
constexpr int factorial14(int n) {
int result = 1;
for (int i = 2; i <= n; i++) {
result *= i;
}
return result;
}
// C++17: if constexpr added
template<typename T>
constexpr auto process(T value) {
if constexpr (std::is_integral_v<T>) {
return value * 2;
} else {
return value;
}
}
Basic Usage
// Simple calculation
constexpr int add(int a, int b) {
return a + b;
}
constexpr int multiply(int a, int b) {
return a * b;
}
// Use as array size
constexpr int SIZE = add(10, 20);
int arr[SIZE]; // Compile-time size
Practical Examples
Example 1: Math Functions
constexpr int fibonacci(int n) {
if (n <= 1) return n;
return fibonacci(n - 1) + fibonacci(n - 2);
}
constexpr int power(int base, int exp) {
int result = 1;
for (int i = 0; i < exp; i++) {
result *= base;
}
return result;
}
constexpr bool isPrime(int n) {
if (n <= 1) return false;
if (n == 2) return true;
if (n % 2 == 0) return false;
for (int i = 3; i * i <= n; i += 2) {
if (n % i == 0) return false;
}
return true;
}
int main() {
constexpr int fib10 = fibonacci(10); // 55 (compile-time)
constexpr int pow = power(2, 10); // 1024
constexpr bool prime = isPrime(17); // true
std::cout << fib10 << std::endl;
std::cout << pow << std::endl;
std::cout << prime << std::endl;
}
Example 2: String Processing
constexpr size_t strlen_constexpr(const char* str) {
size_t len = 0;
while (str[len] != '\0') {
len++;
}
return len;
}
constexpr bool startsWith(const char* str, const char* prefix) {
while (*prefix != '\0') {
if (*str != *prefix) {
return false;
}
str++;
prefix++;
}
return true;
}
int main() {
constexpr size_t len = strlen_constexpr("Hello"); // 5
constexpr bool starts = startsWith("Hello World", "Hello"); // true
char buffer[len + 1]; // Compile-time size
}
Example 3: Hash Function
constexpr unsigned int hash(const char* str) {
unsigned int hash = 5381;
while (*str) {
hash = ((hash << 5) + hash) + *str;
str++;
}
return hash;
}
int main() {
// Compile-time hash
constexpr unsigned int h1 = hash("apple");
constexpr unsigned int h2 = hash("banana");
// Use in switch statement
const char* fruit = "apple";
switch (hash(fruit)) {
case hash("apple"):
std::cout << "Apple" << std::endl;
break;
case hash("banana"):
std::cout << "Banana" << std::endl;
break;
}
}
Example 4: Array Initialization
constexpr int generateValue(int index) {
return index * index;
}
template<size_t N>
constexpr std::array<int, N> generateArray() {
std::array<int, N> arr{};
for (size_t i = 0; i < N; i++) {
arr[i] = generateValue(i);
}
return arr;
}
int main() {
constexpr auto arr = generateArray<10>();
// arr = {0, 1, 4, 9, 16, 25, 36, 49, 64, 81}
for (int x : arr) {
std::cout << x << " ";
}
}
constexpr Classes
class Point {
private:
int x, y;
public:
constexpr Point(int x, int y) : x(x), y(y) {}
constexpr int getX() const { return x; }
constexpr int getY() const { return y; }
constexpr int distanceSquared() const {
return x * x + y * y;
}
};
int main() {
constexpr Point p(3, 4);
constexpr int dist = p.distanceSquared(); // 25
int arr[dist]; // Compile-time size
}
Common Issues
Issue 1: Calling Non-constexpr Function
int nonConstexpr(int x) {
return x * 2;
}
// ❌ Call non-constexpr function
constexpr int func(int x) {
return nonConstexpr(x); // Error
}
// ✅ Call only constexpr functions
constexpr int constexprFunc(int x) {
return x * 2;
}
constexpr int func(int x) {
return constexprFunc(x); // OK
}
Issue 2: Static Variables
// ❌ Static variable (C++11)
constexpr int func() {
static int count = 0; // Error
return count++;
}
// ✅ Allowed from C++14
constexpr int func14() {
static int count = 0; // OK (C++14)
return count++;
}
Issue 3: Virtual Functions
class Base {
public:
// ❌ constexpr virtual function (before C++17)
virtual constexpr int getValue() const {
return 42;
}
};
// ✅ C++20: constexpr virtual allowed
class Base20 {
public:
virtual constexpr int getValue() const {
return 42;
}
};
Summary
Key Points
- constexpr function: Usable at compile-time and runtime
- C++11: Single return statement only
- C++14: Loops and variables allowed
- C++17: if constexpr added
- C++20: Virtual functions allowed
When to Use
✅ Use constexpr when:
- Need compile-time constants
- Want to optimize performance
- Array size calculation
- Template metaprogramming
❌ Don’t use when:
- Function has side effects
- Calls non-constexpr functions
- Too complex (readability matters)
Best Practices
- ✅ Use constexpr for pure functions
- ✅ Combine with templates
- ✅ Use for compile-time optimization
- ❌ Don’t overuse (readability first)
- ❌ Don’t use for I/O operations
Related Articles
Master compile-time programming with constexpr! 🚀
Frequently Asked Questions (FAQ)
Q. When would I use this in practice?
A. C++ constexpr function constexpr int square(int x) { return x * x; }. Organizes from concept to usage with practical exa…
Q. What should I read before this?
A. Follow the previous article or related articles links at the bottom of each post to learn in sequence. See the C++ series index for the full picture.
Q. Where can I study this more deeply?
A. Check cppreference and the relevant library’s official documentation. The reference links at the end of the article are also worth using.
Related Articles (Internal Links)
Other articles related to this topic.
- C++ 컴파일 타임 프로그래밍 | constexpr·consteval·if constexpr 완벽 가이드
- C++ constexpr Lambda | ‘컴파일 타임 람다’ 가이드
- C++ if constexpr | ‘컴파일 타임 if’ 가이드
Keywords Covered in This Article (Related Search Terms)
This article covers C++, constexpr, compile-time, C++11.