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 function은 constant를 생성해야 하므로, 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 값 또는 프로그램 실행 중에 변경되지 않는 모든 데이터에 특히 유용합니다.
챌린지
쉬움코드를 세 개의 파일로 구성합니다:
MathUtils.h: 컴파일 시간 수학 functions를 Define합니다.다음 functions를 Create합니다:
cube:int를 받아 세제곱(n * n * n)을 반환하는constexprfunctiontriangularNumber: 공식 n * (n + 1) / 2를 사용하여 n번째 삼각수를 계산하는constexprfunction. 이 task에서는 항상 컴파일 시간 컨텍스트에서만 호출하여 그 결과를constexpr변수에 저장합니다.sumOfSquares: 두 integers를 받아 그 제곱의 합(a*a + b*b)을 반환하는constexprfunction
Config.h: 컴파일 시간 상수를 사용하여 config 구조를 Create합니다.width,height,depth라는 세 integers를 받는constexprconstructor가 있는Configstruct를 Define합니다. 이를 public members로 저장합니다. 또한 width * height * depth를 반환하는volume()이라는constexprmethod를 추가합니다.struct 아래에 10, 20, 5 값으로 initialized된
DEFAULT_CONFIG라는constexprglobal constant를 Create합니다.main.cpp: runtime 값을 나타내는 두 integers를 input에서 읽습니다.먼저
constexprvariables를 Create하여 컴파일 시간 evaluation을 Demonstrate합니다:cube(4)를 constexpr 변수에 저장하고 출력합니다:Cube of 4: [value]triangularNumber(10)을 constexpr 변수에 저장하고 출력합니다:10th triangular number: [value]- Default config의 volume을 출력합니다:
Default volume: [value]
그런 다음 두 input 값을 사용하여
constexprfunctions가 runtime에서도 작동할 수 있음을 Demonstrate합니다:- 첫 번째 input으로
cube()을 Call하고 출력합니다:Cube of [input]: [result] - both inputs로
sumOfSquares()를 Call하고 출력합니다:Sum of squares: [result]
예를 들어, inputs가 3과 4인 경우:
Cube of 4: 64
10th triangular number: 55
Default volume: 1000
Cube of 3: 27
Sum of squares: 25inputs가 5와 12인 경우:
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;
}
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.
객체 지향 프로그래밍의 모든 레슨
직접 연습해 보세요: 온라인 C++ 컴파일러