Menu
Coddy logo textTech

constexpr와 consteval

Coddy C++ 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨. 104개 중 87번째.

C++에서는 런타임이 아니라 compile 시점에 계산을 수행할 수 있으므로 성능을 크게 향상시킬 수 있습니다. constexpr 키워드(C++11)와 consteval 키워드(C++20)를 사용하면 표현식이 평가되는 시점을 제어할 수 있습니다.

constexpr 함수는 상수 인수가 주어지면 컴파일 시간에 평가될 수 있지만, 상수가 아닌 입력을 사용하여 런타임에 실행될 수도 있습니다.

#include <iostream>

constexpr int square(int n) {
    return n * n;
}

int main() {
    constexpr int compileTime = square(5);  // 컴파일 시간에 평가됨
    
    int x = 7;
    int runtime = square(x);  // 런타임에 평가됨
    
    std::cout << compileTime << "\n";  // 25
    std::cout << runtime << "\n";      // 49
}

컴파일 시 evaluation보장해야 할 때는 consteval을 사용하세요. consteval functionconstant를 생성해야 하므로, runtime 값으로 호출하면 컴파일 오류가 발생합니다:

consteval int factorial(int n) {
    return n <= 1 ? 1 : n * factorial(n - 1);
}

int main() {
    constexpr int result = factorial(5);  // OK: 120이 컴파일 타임에 계산됨
    
    // int x = 5;
    // int bad = factorial(x);  // ERROR: x는 상수가 아님
}

constexpr를 변수 및 클래스 constructor와 함께 사용할 수도 있어, 전체 객체를 컴파일 시점에 생성할 수 있습니다. 이는 조회 테이블, config 값 또는 프로그램 실행 중에 변경되지 않는 모든 데이터에 특히 유용합니다.

challenge icon

챌린지

쉬움

코드를 세 개의 파일로 구성합니다:

  • MathUtils.h: 컴파일 시간 수학 functions를 Define합니다.

    다음 functions를 Create합니다:

    • cube: int를 받아 세제곱(n * n * n)을 반환하는 constexpr function
    • triangularNumber: 공식 n * (n + 1) / 2를 사용하여 n번째 삼각수를 계산하는 constexpr function. 이 task에서는 항상 컴파일 시간 컨텍스트에서만 호출하여 그 결과를 constexpr 변수에 저장합니다.
    • sumOfSquares: 두 integers를 받아 그 제곱의 합(a*a + b*b)을 반환하는 constexpr function
  • Config.h: 컴파일 시간 상수를 사용하여 config 구조를 Create합니다.

    width, height, depth라는 세 integers를 받는 constexpr constructor가 있는 Config struct를 Define합니다. 이를 public members로 저장합니다. 또한 width * height * depth를 반환하는 volume()이라는 constexpr method를 추가합니다.

    struct 아래에 10, 20, 5 값으로 initialized된 DEFAULT_CONFIG라는 constexpr global constant를 Create합니다.

  • main.cpp: runtime 값을 나타내는 두 integers를 input에서 읽습니다.

    먼저 constexpr variables를 Create하여 컴파일 시간 evaluation을 Demonstrate합니다:

    • cube(4)를 constexpr 변수에 저장하고 출력합니다: Cube of 4: [value]
    • triangularNumber(10)을 constexpr 변수에 저장하고 출력합니다: 10th triangular number: [value]
    • Default config의 volume을 출력합니다: Default volume: [value]

    그런 다음 두 input 값을 사용하여 constexpr functions가 runtime에서도 작동할 수 있음을 Demonstrate합니다:

    • 첫 번째 input으로 cube()을 Call하고 출력합니다: Cube of [input]: [result]
    • both inputs로 sumOfSquares()를 Call하고 출력합니다: Sum of squares: [result]

예를 들어, inputs가 34인 경우:

Cube of 4: 64
10th triangular number: 55
Default volume: 1000
Cube of 3: 27
Sum of squares: 25

inputs가 512인 경우:

Cube of 4: 64
10th triangular number: 55
Default volume: 1000
Cube of 5: 125
Sum of squares: 169

직접 해보기

#include <iostream>
#include "MathUtils.h"
#include "Config.h"

using namespace std;

int main() {
    // 입력에서 두 개의 정수를 읽기
    int input1, input2;
    cin >> input1;
    cin >> input2;
    
    // TODO: 컴파일 타임 평가 시연
    // cube(4)를 저장하는 constexpr 변수를 만들고 출력: "Cube of 4: [value]"
    
    // TODO: Create a constexpr variable storing triangularNumber(10)
    // and print: "10th triangular number: [value]"
    
    // TODO: Print the default config's volume: "Default volume: [value]"
    
    // TODO: constexpr 함수의 런타임 사용 시연
    // input1로 cube()를 호출하고 출력: "Cube of [input1]: [result]"
    
    // TODO: Call sumOfSquares() with both inputs
    // and print: "Sum of squares: [result]"
    
    return 0;
}
quiz icon실력 점검

이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.

객체 지향 프로그래밍의 모든 레슨

직접 연습해 보세요: 온라인 C++ 컴파일러