Modern C++ - constexpr

진경천·2024년 3월 19일
0

C++

목록 보기
84/90

컴파일 타임에 실행하여 객체나 함수의 반환값을 컴파일 타임에 값을 알 수 있게 해준다.

이를 상수식이라 부르며 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];

}

constexpr 함수

#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);
}

위와 같이 피보나치 함수를 만들었다고 가정했을 때의 동작을 알아보자

재귀 동작을 하며 계산을 한다.

constexpr

컴파일 타임에 재귀함수를 실행하여 55란 값을 변수 val에 저장한다.

컴파일타임이 길어지는 경우

fib( )의 인자에 50을 주었을 때 결과이다.
constexpr은 컴파일 타임에 실행하기 때문에 기본적으로 컴파일 타임이 길어진다.

하지만 실행시간이 길어 컴파일 타임이 지나치게 길어질 경우 runtime에 실행하게 된다.

if문에서의 constexpr

일반적으로 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 = &num;

	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문만 실행한다.

profile
어중이떠중이

0개의 댓글