constexpr은 constant expression(상수 표현식)의 약자로, 컴파일 타임에 값을 계산할 수 있게하여 더 최적화된 코드를 생성하도록 돕는다.
#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;
}
}
#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;
}
#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 변수에 대입 → 컴파일 타임 실행
- 일반 변수에 대입 → 런타임 실행 (일반 함수와 동일)
#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;
}