[모던C++입문] 5.1 컴파일러가 계산하도록 만들기
- 📕 Book/모던C++입문
- 2021. 7. 23.
5 메타 프로그래밍
5.1 컴파일러가 계산하도록 만들기
- 컴파일 타임 계산은 두가지 방법이 있다.
- 템플릿 메타 함수(Meta-Function)를 사용
- constexpr을 사용 (C++11)
컴파일 타임 함수
constexpr long fibonacci(long n)
{
return n <= 2 ? 1 : fibonacci(n-1) + fibonacci(n-2);
}
- constexpr에 들어갈 수 있는 문장은 제한적
- 함수 외부에서는 읽거나 쓸수 없다. 사이드 이펙트가 없다.
- 변수를 포함할 수 없다.
- if 또는 for와 같은 제어문을 포함할 수 없다.
- 단일 계산문만 포함할 수 있다.
- constexpr인 함수만 호출할 수 있다.
- 템플릿 메타 함수와 비교시
- 부동소수점 타입을 전달할 수 있다.
- 사용자 정의 타입을 처리할 수도 있다.
- 타입 검출을 사용할 수 있다.
- 멤버 함수를 정의할 수 있다.
- 조건문을 사용할 수 있다.
- 런타임 인수를 사용해 함수를 호출할 수 있다.
확장된 컴파일 타임 함수 (C++14)
- void함수가 가능해짐
constexpr void square(int& x) { x *= x; }
- 다음 조건을 만족하는 지역변수
- 초기화되어 있다.
- static이 아니며, thread 저장기간도 없다
- 리터럴 타입을 갖는다.
- 다음을 제외한 제어문
- goto
- 어셈블리 코드 (asm블록)
- try 블록
//C++14에서만 가능
template<typename T>
constexpr T power(const T& x, int n)
{
T r(1);
while(--n > 0)
r *= x;
return r;
}
소수판정
// 1은 소수가 아니다
// 2를 제외한 짝수는 소수가 아니다.
// 1보다 큰 홀수와 자기 자신보다 작은수로 나눌수 없는가?
// 자신의 제곱근 값보다 낮은수까지만 검사해도 된다
const bool is_prime(int i)
{
if( i == 1)
return false;
if( i % 2 == 0 )
return i == 2;
int max_check = static_cast<int>(sqrt(i)) + 1;
for( int j = 3; j < max_check; j += 2 )
if( i % j == 0 )
return false;
return true;
}
상수는 어떻게 불변 상태가 되는가?
const int i = something;
- 위 코드는 두가지 불변성을 설정
- 프로그램 실행 중에 개체를 변경할 수 없다.
- 컴파일 타임에 이 값을 이미 알고 있다.
- something이 리터럴이라면 컴파일 동안 사용가능
- 변수를 const 개체에 할당하는 경우 컴파일하는 동안 사용 불가
const long i = 7, j - 8;
template<long N>
struct static_long
{
struct const long value = N;
};
const long k = i + j;
static_long<k> = sk;
long ll;
cin >> ll;
const long cl = ll;
static_long<cl> scl; //오류
반응형