[C/C++] constexpr

할랑말랑·2026년 3월 12일

C/C++

목록 보기
20/45

1. constexpr C++11

constexpr은 constant expression(상수 표현식)의 약자로, 컴파일 타임에 값을 계산할 수 있게하여 더 최적화된 코드를 생성하도록 돕는다.

  • const 는 런타임, 컴파일 타임에 결정
  • constexpr은 컴파일 타임에 결정
#include <iostream>

int constRand()
{
    return 0;
}

// C++11: 단일 return문만 가능
constexpr int square(int x)
{
    return x * x;
}

// 재귀는 가능
constexpr int factorial(int n)
{
    return n <= 1 ? 1 : n * factorial(n - 1);
}

int main()
{
    // const
    const int a = 10;                 // OK - 컴파일 타임 초기화
    const int b = rand();             // OK - 런타임에 결정

    // constexpr
    constexpr int c = a + 10;         // OK
    // constexpr int d = constRand(); // 에러! 컴파일 타임에 알 수 없음

    constexpr int size = 100;
    int array[size];                  // OK - 컴파일 타임 상수

    constexpr double pi = 3.14159;
    constexpr int squared = size * size;

    constexpr int value = square(5);  // 컴파일 타임에 25로 계산
    int arr[square(4)]{ 0 };          // 컴파일 타임에 16로 계산

    for (int i = 0; i < square(4); i++)
    {
        arr[i] = i + 1;
    }

    for (int i = 0; i < square(4); i++)
    {
        std::cout << arr[i] << std::endl;
    }
}

2. C++14 constexpr 함수 확장

  • 더 복잡한 로직 허용

#include <iostream>
#include <array>

// C++14: 여러 문장, 지역 변수, 루프 가능
constexpr int fibonacci(int n)
{
    if (n <= 1)
        return n;

    int a = 0, b = 1;

    for (int i = 2; i <= n; ++i)
    {
        int temp = a + b;
        a = b;
        b = temp;
    }

    return b;
}

// void 반환도 가능
constexpr void swap(int& a, int& b)
{
    int temp = a;
    a = b;
    b = temp;
}

constexpr auto sortArray()
{
    std::array<int, 5> arr = { 5, 2, 8, 1, 9 };
    // 정렬
    for (size_t i = 0; i < arr.size(); ++i)
    {
        for (size_t j = 0; j < arr.size() - 1; ++j)
        {
            if (arr[j] > arr[j + 1])
                swap(arr[j], arr[j + 1]);
        }
    }
    return arr;
}

int main()
{
    constexpr int fib10 = fibonacci(10); // 컴파일 타임: 55

    constexpr auto sortArr = sortArray(); // 컴파일 타임: 배열 {1, 2, 5, 8, 9}

    for (auto a : sortArr)
    {
        std::cout << a << std::endl;
    }

    std::cout << fib10 << std::endl;
}
  • constexpr, noconstexpr

#include <iostream>

constexpr int getValue(int x)
{
    return x * 2;
}

int main()
{
    // 컴파일 타임 사용
    constexpr int compile_time = getValue(10);

    // 런타임 사용도 가능
    int runtime_input;
    std::cin >> runtime_input;
    int runtime_result = getValue(runtime_input);
}

constexpr 함수 = "컴파일 타임에 실행될 수 있는" 함수

  • constexpr 변수에 대입 → 컴파일 타임 실행
  • 일반 변수에 대입 → 런타임 실행 (일반 함수와 동일)

3. C++17 constexpr 람다/ if constexpr

  • if constexpr

    컴파일 타임에 조건을 평가하여 코드경로를 결정한다
    조건이 거짓인 분기는 컴파일 되지않는다.
#include <iostream>
#include <type_traits>

template<typename T>
void print(T value)
{
    // 일반 if - 둘 다 컴파일됨
    if (std::is_integral_v<T>)
    {
        std::cout << "정수: " << value << std::endl;
    }
    else
    {
        std::cout << "실수: " << std::fixed << value << std::endl;
    }
    // 문제: T가 int여도 else 블록이 컴파일되어야 함
}

template<typename T>
void printConstexpr(T value)
{
    // if constexpr - 한 쪽만 컴파일됨
    if constexpr (std::is_integral_v<T>)
    {
        std::cout << "정수: " << value << std::endl;
    }
    else
    {
        std::cout << "실수: " << std::fixed << value << std::endl;
    }
    // T가 int면 else 블록은 아예 컴파일 안 됨!
}

int main()
{
    printConstexpr(1);
    printConstexpr(1.2f);
    return 0;
}
  • 각 타입마다 별도의 함수가 생성됨거짓인 분기는 바이너리에 포함되지 않음마치 두 개의 다른 함수를 작성한 것과 동일한 효과

constexpr 람다

[C/C++] 람다 표현식 참고

0개의 댓글