컴파일 타임에 실행하여 객체나 함수의 반환값을 컴파일 타임에 값을 알 수 있게 해준다.
이를 상수식이라 부르며 constexpr로서 표현한다.
#include <iostream>
using namespace std;
int sum(int a, int b, int c) {
return a + b + c;
}
int main() {
int a = 1;
int b = 2;
int c = 3;
int d = sum(a, b, c);
cout << d << endl;
return 0;
}
#include <iostream>
using namespace std;
constexpr int sum(int a, int b, int c) {
return a + b + c;
}
int main() {
constexpr int a = 1;
constexpr int b = 2;
constexpr int c = 3;
int d = sum(a, b, c);
cout << d << endl;
return 0;
}
위 예제를 보면 constexpr로 상수식을 표현했을 때 컴파일타임에 sum함수가 실행이되어 런타임 에는 함수호출 조차 안된것을 볼 수 있다.
상수식을 인자로 받는 template에도 constexpr을 적용할 수 있다.
마찬가지로 배열과 enum등의 상수식을 인자로 받는 경우에도 사용할 수 있다.
#include <iostream>
using namespace std;
template<long long N>
void print() {
cout << N << endl;
}
int main() {
const int num = 10;
constexpr int val = num;
print<val>();
int nums[val];
}
#include <iostream>
using namespace std;
int fib(int n) {
return n <= 1 ? n : fib(n - 2) + fib(n - 1);
}
int main() {
int val = fib(10);
}
위와 같이 피보나치 함수를 만들었다고 가정했을 때의 동작을 알아보자
재귀 동작을 하며 계산을 한다.
컴파일 타임에 재귀함수를 실행하여 55란 값을 변수 val
에 저장한다.
fib( )의 인자에 50을 주었을 때 결과이다.
constexpr은 컴파일 타임에 실행하기 때문에 기본적으로 컴파일 타임이 길어진다.
하지만 실행시간이 길어 컴파일 타임이 지나치게 길어질 경우 runtime에 실행하게 된다.
일반적으로 if문은 먼저 if문의 조건을 실행 후 if문이 반환한 bool값에 따라 if문안의 실행문 혹은 else를 실행하게 된다.
하지만 constexpr을 사용하게 되면 컴파일 타임에 조건문 실행이 가능해 코드를 조금 더 간결하게 할 수 있다.
#include <iostream>
using namespace std;
template<typename T>
void getValue(T t) {
if constexpr (std::is_pointer<T>()) // constexpr이 없으면 컴파일이 안됨
cout << *t << endl;
else
cout << t << endl;
}
int main() {
int num = 10;
int* pNum = #
getValue(num);
getValue(pNum);
}
실행결과
10
10
getValue(num) : constexpr을 통해 컴파일 타임에 std::is_pointer<int>
가 실행되어 false를 반환했고 runtime에는 else만 실행한다.
getValue(num) : constexpr을 통해 컴파일 타임에 std::is_pointer<int*>
가 실행되어 false를 반환했고 runtime에는 if문만 실행한다.