templatetypename T class SArray public explicit SArray sizet
단순 배열 클래스 template<typename T> class SArray { public: explicit SArray (size_t s) //생성자 : storage(new T[s]), storage_size(s) { init(); }
단순 배열 클래스 SArray (SArray<T>const& orig ) //복사생성자 : storage(new T[orig. size()]) , storage_size(orig. size()) { copy(orig); }
단순 배열 클래스 //할당연산자 SArray<T>& operator= (SArray<T>const& orig) { if (&orig!=this) { copy(orig); } return *this; }
단순 배열 클래스 //크기반환 size_t size() const { return storage_size; }
단순 배열 클래스 //인덱스연산자 T operator[] (size_t idx) const { return storage[idx]; } T& operator[] (size_t idx) { return storage[idx]; }
단순 배열 클래스 protected: //생성자 보조함수 void init() { for (size_t idx = 0; idx<size(); ++idx) { storage[idx] = T(); } }
단순 배열 클래스 //복사 생성자와 할당 연산자 보조함수 void copy (SArray<T> const& orig) { assert(size()==orig. size()); for (size_t idx = 0; idx<size(); ++idx) { storage[idx] = orig. storage[idx]; } }
단순 배열 클래스 //멤버변수 private: T* storage; size_t storage_size; };
단순 배열 클래스 덧셈연산 template<typename T> SArray<T> operator+ (SArray<T> const& a, SArray<T> const& b) { SArray<T> result(a. size()); for (size_t k = 0; k<a. size(); ++k) { 배열… result[k] = a[k]+b[k]; } return result; }
단순 배열 클래스 곱셈연산 template<typename T> SArray<T> operator* (SArray<T> const& a, SArray<T> const& b) { SArray<T> result(a. size()); for (size_t k = 0; k<a. size(); ++k) { 배열… result[k] = a[k]*b[k]; } return result; }
단순 배열 클래스 스칼라와 곱셈연산 template<typename T> SArray<T> operator* (T const& s, SArray<T> const& a) { SArray<T> result(a. size()); for (size_t k = 0; k<a. size(); ++k) { result[k] = s*a[k]; } return result; } 배열…
단순 배열 클래스 int main() { SArray<double> x(1000), y(1000); //. . . x = 1. 2*x + x*y; }
단순 배열 클래스 template<class T> SArray<T>& SArray<T>: : operator+= (SArray<T> const& b) { for (size_t k = 0; k<size(); ++k) { (*this)[k] += b[k]; } return *this; }
단순 배열 클래스 template<class T> SArray<T>& SArray<T>: : operator*= (SArray<T> const& b) { for (size_t k = 0; k<size(); ++k) { (*this)[k] *= b[k]; } return *this; }
단순 배열 클래스 template<class T> SArray<T>& SArray<T>: : operator*= (T const& s) { for (size_t k = 0; k<size(); ++k) { (*this)[k] *= s; } return *this; }
단순 배열 클래스 int main() { SArray<double> x(1000), y(1000); //. . . // process x = 1. 2*x + x*y SArray<double> tmp(x); tmp *= y; x *= 1. 2; x += tmp; }
우리가 원하는 계산 방식 int main() { SArray <double> x(1000), y(1000); //. . . for ( int idx = 0; idx < x. size(); ++idx ) { x[idx] = 1. 2*x[idx] + x[idx]*y[idx]; } }
표현식 템플릿의 피연산자 template <typename T, typename OP 1, typename OP 2> class A_Add { private: // 나중에 알려드립니다 typename A_Traits<OP 1>: : Expr. Ref op 1; typename A_Traits<OP 2>: : Expr. Ref op 2;
표현식 템플릿의 피연산자 size_t size() const { assert (op 1. size()==0 || op 2. size()==0 || op 1. size()==op 2. size() ); return op 1. size()!=0 ? op 1. size() : op 2. size(); } };
표현식 템플릿의 피연산자 template <typename T, typename OP 1, typename OP 2> class A_Mult { private: //나중에. . typename A_Traits<OP 1>: : Expr. Ref op 1; typename A_Traits<OP 2>: : Expr. Ref op 2;
표현식 템플릿의 피연산자 size_t size() const { assert (op 1. size()==0 || op 2. size()==0 || op 1. size()==op 2. size() ); return op 1. size()!=0 ? op 1. size() : op 2. size(); } };
표현식 템플릿의 피연산자 template <typename T> class A_Scalar { private: T const& s; public: A_Scalar (T const& v) : s(v) { } T operator[] (size_t) const { return s; } size_t size() const { return 0; }; };
표현식 템플릿의 피연산자 template <typename T> class A_Traits { public: typedef T const& Expr. Ref; }; template <typename T> class A_Traits<A_Scalar<T> > { public: typedef A_Scalar<T> Expr. Ref; };
Array형 template <typename T, typename Rep = SArray<T> > class Array { private: Rep expr_rep; public: //생성자 explicit Array (size_t s) : expr_rep(s) { } //복사 생성자 Array (Rep const& rb) : expr_rep(rb) { }
Array형 //할당연산자 Array& operator= (Array const& b) { assert(size()==b. size()); for (size_t idx = 0; idx<b. size(); ++idx) { expr_rep[idx] = b[idx]; } return *this; }
Array형 template<typename T 2, typename Rep 2> Array& operator= (Array<T 2, Rep 2> const& b) { assert(size()==b. size()); for (size_t idx = 0; idx<b. size(); ++idx) { expr_rep[idx] = b[idx]; } return *this; } //다른 타입에 대한 할당 연산자
Array형 //크기 반환 size_t size() const { return expr_rep. size(); }
Array형 T operator[] (size_t idx) const { assert(idx<size()); return expr_rep[idx]; } T& operator[] (size_t idx) { assert(idx<size()); return expr_rep[idx]; }
Array형 Rep const& rep() const { return expr_rep; } Rep& rep() { return expr_rep; } };
코드가 참 어렵습니다 class A { public: A(B const& b) {} }; class B { public: B(C const& c, D const& d) {} }; A f(C const& c, D const& d) { return A(B(c, d)); }
덧셈 연산자 template <typename T, typename R 1, typename R 2> Array<T, A_Add<T, R 1, R 2> > operator+ (Array<T, R 1> const& a, Array<T, R 2> const& b) { return Array<T, A_Add<T, R 1, R 2> > (A_Add<T, R 1, R 2>(a. rep(), b. rep())); }
생성자 코드 Array<T, A_Add<T, R 1, R 2> > (A_Add<T, R 1, R 2>( a. rep(), b. rep() ));
operator+ SArray A_Scalar A_Add Array SArray
곱셈 연산자 template <typename T, typename R 1, typename R 2> Array<T, A_Mult<T, R 1, R 2> > operator* (Array<T, R 1> const& a, Array<T, R 2> const& b) { return Array<T, A_Mult<T, R 1, R 2> > (A_Mult<T, R 1, R 2>(a. rep(), b. rep())); }
operator* SArray A_Scalar A_Mult Array SArray
스칼라 곱셈 연산자 template <typename T, typename R 2> Array<T, A_Mult<T, A_Scalar<T>, R 2> > operator* (T const& s, Array<T, R 2> const& b) { return Array<T, A_Mult<T, A_Scalar<T>, R 2> > (A_Mult<T, A_Scalar<T>, R 2>(A_Scalar<T>(s), b. rep())); }
operator* double SArray double A_Scalar A_Mult Array SArray
연산을 추적 해보자 int main() { Array<double> x(1000), y(1000); //. . . x = 1. 2*x + x*y; }
연산을 추적 해보자 1. 2*x (double, Array<double, Sarray<double> >) template <typename T, typename R 2> Array<T, A_Mult<T, A_Scalar<T>, R 2> > operator* (T const& s, Array<T, R 2> const& b) { return Array<T, A_Mult<T, A_Scalar<T>, R 2> > (A_Mult<T, A_Scalar<T>, R 2>(A_Scalar<T>(s), b. rep())); }
operator* double SArray double A_Scalar A_Mult Array SArray
연산을 추적 해보자 x*y (Array<double, Sarray<double> >) template <typename T, typename R 1, typename R 2> Array<T, A_Mult<T, R 1, R 2> > operator* (Array<T, R 1> const& a, Array<T, R 2> const& b) { return Array<T, A_Mult<T, R 1, R 2> > (A_Mult<T, R 1, R 2>(a. rep(), b. rep())); }
operator* SArray A_Scalar A_Mult Array SArray
연산을 추적 해보자 1. 2*x + x*y template <typename T, typename R 1, typename R 2> Array<T, A_Add<T, R 1, R 2> > operator+ (Array<T, R 1> const& a, Array<T, R 2> const& b) { return Array<T, A_Add<T, R 1, R 2> > (A_Add<T, R 1, R 2>(a. rep(), b. rep())); }
double operator+ A_Scalar A_Mult Array SArray double A_Scalar A_Mult A_Add Array SArray A_Scalar A_Mult SArray
연산을 추적 해보자 template<typename T 2, typename Rep 2> Array& operator= (Array<T 2, Rep 2> const& b) { assert(size()==b. size()); for (size_t idx = 0; idx<b. size(); ++idx) { expr_rep[idx] = b[idx]; } return *this; }
template <typename T, typename Rep = SArray<T> > class Array { double T& operator[] (size_t idx) A_Scalar SArray A_Mult { A_Add assert(idx<size()); Array return expr_rep[idx]; } }; A_Scalar A_Mult SArray
연산을 추적 해보자 template <typename T, typename OP 1, typename OP 2> class A_Add { public: double //할당 연산자 A_Scalar SArray A_Multconst T operator[] (size_t idx) A_Add { return op 1[idx] + op 2[idx]; } }; A_Scalar A_Mult SArray
연산을 추적 해보자 template <typename T, typename OP 1, typename OP 2> class A_Mult { public: //할당 연산자 double T operator[] (size_t idx) const A_Scalar SArray A_Mult { return op 1[idx] * op 2[idx]; } }; A_Scalar A_Mult SArray
표현식 템플릿 할당 template<typename T, typename A 1, typename A 2> class A_Subscript { public: A_Subscript (A 1 const& a, A 2 const& b) : a 1(a), a 2(b) { }
표현식 템플릿 할당 T operator[] (size_t idx) const { return a 1[a 2[idx]]; } T& operator[] (size_t idx) { return a 1[a 2[idx]]; }
표현식 템플릿 할당 size_t size() const { return a 2. size(); } private: A 1 const& a 1; A 2 const& a 2; };
표현식 템플릿 할당 template < typename T 2, typename R 2> inline Array<T, A_Subscript<T, R, R 2> > Array<T, R>: : operator[](Array<T 2, R 2> const& b) { return Array<T, A_Subscript<T, R, R 2> > (A_Subscript<T, R, R 2>(*this, b)); }
- Slides: 97