본문으로 건너뛰기 C++ constexpr Function | 'Compile-Time Function' Guide

C++ constexpr Function | 'Compile-Time Function' Guide

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

  1. constexpr function: Usable at compile-time and runtime
  2. C++11: Single return statement only
  3. C++14: Loops and variables allowed
  4. C++17: if constexpr added
  5. 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

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.


Other articles related to this topic.


Keywords Covered in This Article (Related Search Terms)

This article covers C++, constexpr, compile-time, C++11.