C++ Template, Expression Templates #4

Short Articles 2012. 2. 22. 20:05
표현식 템플릿은 숫자 배열 클래스를 지원하기 위해 고안된 프로그램이 기술입니다
이번 아티클은 다음과 같이 진행합니다
1. 단순한 배열 클래스 구현하여 배열 연산에 대한 문제제기
2. 표현식 템플릿 구현
3. 표현식 템플릿을 아는 랩퍼클래스 구현
4. 실재 표현식 템플릿 사용해서 어떻게 동작하는 방법 추적  
전체 표현식을 다 읽기 전에는 표현식의 일부만 계산하지 않고 전체 계산하기전에 어떤 객체에 무슨 연산이 적용되었는지 기록하는 것이 표현식 템플릿의 핵심입니다

 첫시간에 SArray 단순 배열 클래스를 만들었습니다
두번째에 A_Add, A_Mult, A_Scalar에 대해서 배웠습니다
(스칼라 때문에 A_Traits 이라는 특질클래스도 배웠습니다)
세번째에 Array 클래스와 연산자 배웠습니다

처음으로 돌아가서 배열 연산을 해봅시다

이 연산 부터 알아봅시다
1.2*x
연산자 오버로딩 중에 스칼라와 배열 곱셈연산이 호출됩니다

지저분 하네요 --; 이전에 설명 했습니다
템플릿 인자 추론(template argument deduction)이 되네요
operator* 의 Parameters : Arguments 로 구분하면
T const& s                :               1.2
Array const& b           :               x
T는 double 이고 R2는 SArray
double const& s , Array const& b 입니다
리턴타입
Array<T,A_Mult<T,A_Scalar<T>,R2> > 은  A_Scalar<T>와 R2 곱셈연산 결과를  A_Mult<T,A_Scalar<T>,R2> 가지고 있고 다른 곱셈 및 덧셈에 연산하기 위해 Array 래퍼클래스에 담고 있습니다
해당 객체를 생성자 리턴하는 아주 간결한(?) 코드 입니다
그러니까 A( B(c,d) ) 이런 구문이라고 할까요?
A객체를 생성하려면 B객체를 필요하고 B객체를 생성하려면 c,d 가 필요한경우 입니다

Array<...>(...) 결국 껍데기는  Array 이거이죠. 생성자를 호출한 코드입니다
Array<T,A_Mult<...> >(A_Mult<...>(...) ) Array에 실재 저장 하는 배열클래스를 넣어야 합니다 Array 생성자에 인수가 넣어야 하잖아요 그럼 Array는 끝났습니다 그런데  A_Mult가 남았네요 A_Mult 생성자를 넣어야 합니다
Array<T,A_Mult<T,A_Scalar<T>,R2> >(A_Scalar<T>(s), b.rep())); 그래서 이렇게 나왔습니다

 x*y
두 배열의 곱셈연산이 호출됩니다

이 연산도 설명해드려야 하는 거죠?? ㅡㅡ;
인자추론을 하면
Array<T,R1> const& a   :   x
Array<T,R2> const& b   :   y
T는 double 이고 R1는 SArray R2는 SArray 입니다
두 배열간 곱셈 연산도 생성자 호출인데요 
A( B(c,d) ) 이런형식 입니다
 
1.2*x + x*y
더하기 입니다

이것도 동일합니다 인자추론하면 어떨까요?
Array<T,R1> const& a    :     1.2*x  타입은  Array<double, A_Mult< double ,A_Scalar< double >,SArray> >
Array<T,R2> const& b    :      x*y  타입은   Array< double , A_Mult< double , SArray , SArray > >
T는 double이고 R1는  A_Mult< double ,A_Scalar< double >,SArray> , R2는  A_Mult< double , SArray , SArray > 입니다

리턴타입은   Array<double, A_Add<double,  A_Mult< double ,A_Scalar< double >,SArray> ,
   A_Mult< double , SArray , SArray > > >입니다

겁나 거대한 클래스가 만들어졌습니다
어떤 객체에 무슨 연산이 적용되었는지 기록 한 객체가 만들어 졌습니다
이제 실제 연산을 해봅시다
x = 1.2*x + x*y 

 Array의 할당연산자는 이렇게 구현되어 있었습니다

반복문을 돌면서 할당하고 있습니다
[]연산자를 사용하고 있네요 A_Add 에서는

 op1[idx] + op2[idx]
op1 은 A_Mult< double ,A_Scalar< double >,SArray>
op2 는 A_Mult< double , SArray , SArray >
[] 연산자를 사용합니다 A_Mult 에서는

이렇게 됩니다
Array의 할당 연산이 배열크기만큼 할당을 하며,
A_Add, A_Mult 의 [] 연산이 자신들이 저장하고 있는 배열의 계산을 해버립니다
실질적으로 이런연산이 됩니다

발표자료 올립니다
버전업 되었습니다



'Short Articles' 카테고리의 다른 글

Function Template  (0) 2012.03.31
음의 정수의 표현, 보수법  (1) 2012.02.27
C++ Template, Expression Templates #3  (0) 2012.02.21
C++ Template, Expression Templates #2  (0) 2012.02.17
C++ Basic Concept, Storage Duration  (0) 2012.02.10
: