[ Effective C++ ] 항목 48 : 템플릿 메타프로그래밍, 하지 않겠는가?

Minsu._.Lighting·2023년 12월 14일
0

[ Effective C++ ] 정리 모음집
" C++ 프로그래머의 필독서, 스콧 마이어스의 Effective C++ 를 읽고 내용 요약 / 정리 "

[핵심]

" TMP를 통해 기존 작업을 런타임에서 컴파일 타임으로 전환함으로써 얻는 효율 향상을 경험하면 잊기 힘들 것! "

  • 템플릿 메타프로그래밍은 기존 작업을 런타임에서 컴파일 타임으로 전환하는 효과를 낸다. 따라서 TMP를 쓰면 선행 에러 탐지와 높은 런타임 효율을 손에 거머쥘 수 있다.
  • TMP는 정책 선택의 조합에 기반하여 사용자 정의 코드를 생성하는데 쓸 수 있으며, 또한 특정 타입에 대해 부적절한 코드가 만들어지는 것을 막는 데도 쓸 수 있다.

💡 템플릿 메타 프로그래밍(template metaprogramming : TMP)

  • TMP는 컴파일 도중에 실행되는 템플릿 기반의 프로그램을 작성하는 일을 말한다
    - 템플릿 메타프로그램은 C++ 컴파일러가 실행시키는 C++로 만들어진 프로그램
    - TMP 프로그램이 실행을 마친 후엔 그 결과로 나온 출력문이 다시 보통의 컴파일 과정을 거치는 일

  • TMP는 누가 작정하고 만든게 아닌 발굴된 것
    - C++은 TMP를 염두에 두고 설계되지 않았으나 TMP의 뛰어난 유용성이 하나 둘 드러나면서 C++ 언어 및 표준 라이브러리에 TMP를 용이하게 만드는 확장 요소들이 추가 될 여지까지 생김

📌 TMP를 사용하면?

[ TMP의 강점 ]

  • 다른 방법으로는 까다롭거나 불가능한 일을 굉장히 쉽게 할 수 있다
  • TMP를 사용한 프로그램은 C++ 컴파일이진행되는 동안에 실행되기 때문에, 기존 작업을 런타임 영역에서 컴파일 영역으로 전환할 수 있다

[ 위 강점으로 인해 얻는 효과들 ]

  • 런타임에 잡혀왔던 몇몇 에러들을 컴파일 도중에 찾을 수 있다
  • TMP를 써서 만든 C++ 프로그램이 확실히 모든 면에서 효율적일 여지가 많다
    - 실행 코드가 작아지고, 실행 시간도 짧아지며, 메모리도 적게 차지

📌 TMP 사용 예시

template<typename IterT, typename DistT>
void advance(IterT& iter, DistT d)
{
	if(typeid(typename iterator_traits<IterT>::iterator_category) ==
    	typeid(random_acces_iterator_tag))
        {
        	iter += d;
        }
    else
    {
    	if(d >= 0)
        {
        	while(d--)
            	++iter;
        }
        else
        {
        	while (d++)
            	--iter;
        }
    }
}
  • typeid 연산자를 쓰는 방법은 특성정보(traits)를 쓰는 방법보다 효율이 떨어진다
    - 타입 점검 동작은 런타임에 일어나기 때문에 코드 또한 실행 파일에 들어가게 된다

📢 TMP를 썼다면?

  • 주어진 타임에 대한 코드가 별도의 함수로 분리
  • 각각의 함수는 자신이 맡은 타입에 대한 연산만 수행

📌 TMP 에서의 루프

template<unsigned n>
struct Factorial
{
	enum { value = n * Factorial<n-1>::value };
};

template<>
struct Factorial<0>
{
	enum { value = 1 };
};

int main()
{
	cout << Factorial<5>::value;		// 120을 런타임 계산 없이 출력
    cout << Factorial<10>::value;		// 3628800을 런타임 계산 없이 출력
}
  • TMP 에는 반복 의미의 진정한 루프는 없기에 재귀를 사용해 루프 효과를 낸다
    - 재귀 함수 호출이 아닌 재귀식 템플릿 인스턴스화를 한다.

  • value 변수는 나열자 둔갑술을 이용한 것
    - [ 항목 2 : #define을 쓰려거든 const, enum, inline을 떠올리자 ] 참조
    - TMP는 재귀식 템플릿 인스턴스화를 사용해 만들었기에 템플릿 인스턴스화 버전마다 자체적으로 value의 사본을 갖는다. 즉, 루프를 한 번 돌 때마다 그 값이 각각의 value에 담긴다


📌 TMP가 쓰이기 좋은 경우

  • 치수 단위의 정확성 확인
    - TMP를 사용하면 프로그램 안에서 쓰이는 모든 치수 단위의 조합이 제대로 됐는지를 계산 시간에 상관 없이 컴파일 동안에 맞춰 볼 수 있다
    - 분수식 지수 표현이 지원된다

  • 행렬 연산의 최적화
    -TMP를 응용한 고급 프로그래밍 기술인 표현식 템플릿을 사용하면 덩치 큰 임시 객체를 없에는 것은 물론이고 루프까지 합쳐 버릴 수 있다

  • 맞춤식 디자인 패턴 구현의 생성
    - 전략, 감시자, 방문자 패턴 등의 디자인 패턴은 그 구현 방식이 여러 가지일 수 있다, TMP를 사용한 프로그래밍 기술인 정책 기반 설계 라는 것을 사용하면 따로따로 마련된 설계상의 선택을 나타내는 템플릿을 만들어 낼 수 있다
    - 사실 이 기술은 디자인 패턴 혹은 스마트 포인터 등으로 대표되는 프로그래밍 구조물의 영역을 뛰어넘어 일반화 되어 있다, 생성식 프로그래밍의 기초가 바로 이 기술이다.

profile
오코완~😤😤

0개의 댓글

관련 채용 정보