[모던C++입문] 5.3 표현식 템플릿

    표현식 템플릿

    간단한 연산자 구현

    template<typename T>
    inline vector<T> operator+(const vector<T>& x, const vector<T>& y)
    {
        x.check_size(size(y));
        vector<T> sum(size(x));
        for(int i = 0; i < size(x); i++)
            sum[i] = x[i] + y[i];
        return sum;
    }
    
    vector<float> x,y,z,w;
    
    w = x + y + z;
    • 다음과 같은 연산 횟수가 수행된다
      • 덧셈 2n번
      • 할당 3n번
      • 읽기 5n번
      • 쓰기 3n번
      • 메모리 할당 2번
      • 메모리 할당 해제 2번

    • 단일 반복문이나 인라인 함수로 작성한다면
    template<typename T>
    void inline add3(const vector<T>& x, const vector<T>& y, const vector<T>& z, vector<T>& sum)
    {
        x.check_size(size(y));
        x.check_size(size(z));
        x.check_size(size(sum));
        for(int i = 0; i < size(x); i++)
            sum[i] = x[i] + y[i] + z[i];
    }
    
    add3(x, y, z, w);
    • 위 함수의 연산 횟수는
      • 덧셈 2n번
      • 할당 n번
      • 읽기 3n번
      • 쓰기 n번

    표현식 템플릿 클래스

    • 표현식 템플릿(Exppression Template, ET)의 목적은 임시 연산자로 인한 오버헤드를 발생시키지 않고 원래의 연산자 표기법을 유지하는데 있다.
    template<typename T>
    class vector_sum
    {
    public:
        vector_sum(const vector<T>& v1, const vector<T>& v2)
            : v1(v1), v2(v2) { }
    private:
        const vector<T> v1, v2;
    }
    
    template<typename T>
    vector_sum<T> operator+(const vector<T>& x, const vector<T>& y)
    {
        return {x, y};
    }
    //이제 x + y를 할수 있지만 w = x + y는 불가
    
    //w = x + y를 위해 대입 연산자 추가
    vector& operator=(const vector_sum<T>& that)
    {
        check_size(size(that));
        for( int i = 0; i < my_size; ++i)
            data[i] = that[i];
        return *this;
    }

    제네릭 표현식 템플릿

    //임의의 인수를 갖는 표현식 클래스
    template<typename v1, typename v2>
    class vector_sum
    {
        //혼합 산술 연산에 대비하기위해 인수의 값 타입인 common_type_t를 사용
        using value_type = std::common_type_t<typename T1::value_type, typename T2::value_type>;
        value_type operator[](int i) const { return v1[i] + v2[i]; }
    }
    
    //대입 연산자 또한 일반화
    template<typename T>
    class vector
    {
    public:
        template<typename Src>
        vector& operator=(const Src& that)
        {
            check_size(size(that));
            for(int i = 0; i < my_size; i++)
                data[i] = that[i];
            return *this;
        }
    }
    반응형

    댓글

    Designed by JB FACTORY