7.27(금) C++ - iterator 의 구현

from Study/C++ 2007/07/30 14:48 view 19936

#include <iostream>

using namespace std;

 

template<typename T> class slist

{

        struct Node

        {

               T         data;

               Node* next;

               Node( T d, Node* n ) : data(d), next(n) {}

        };

        Node* head;

public:

        slist() : head(0)      {}

 

        void push_front( T a ) { head = new Node( a, head ); }

 

        // list의각요소를접근하기위해스마트포인터를넣는다.

        // 내포로만들거나외부에(그리고내부에typedef로선언) 만들수있다.

        class iterator

        {

               Node* current;

        public:

               typedef T value_type;

               iterator( Node* init = 0 ) : current( init ) {}

 

               iterator& operator++()

               {

                       current = current->next;

                       return *this;

               }

               T& operator* ()

               {

                       return current->data;

               }

               bool operator !=( const iterator& i )

               {

                       return (current != i.current);

               }

        };

        //-------------------------------------------------------

        // 이제slist의처음과past the end iterator를리턴하는함수를제공한다.

        iterator begin() { return iterator(head); }

        iterator end() { return iterator( 0 ); }

};

/*

// 주어진구간의합을출력하는알고리즘을만들고싶다.

 

// 컴파일러에의한타입추론(type ??), 타입을알지못하므로컴파일러에게맡긴다??

// 단점: 리턴값을갖지못한다. 타입을모르므로?? void!!

template<typename T, typename T2> void sum_imp( T first, T last, T2 init )

{

        T2 s = init;

 

        while ( ++first != last )

        {

               s = s + *first;

        }

        cout << s << endl;

}

template<typename T> void sum( T first, T last )

{

        sum_imp( first, last, *first );

}

*/

 

// 버전2. 주어진구간의합을리턴하는함수를만들어보자.

// 모든반복자는자신과연관된typetypedef로가지고있다.( value_type으로꺼내면된다. )

 

// 간접층을만들어type문제를해결한다. (int, int), 반복자특성클래스.

template<typename T> struct xiterator_traits

{

        typedef typename T::value_type value_type;

};

 

// template 부분전문화( 포인터로되어있는것)

template<typename T> struct xiterator_traits<T*>

{

        typedef T value_type;

};

 

template<typename T>
typename xiterator_traits<T>::value_type sum( T first, T last )

{

        //typename T::value_type s = *first;
        //
어떠한타입이올지모르므로0을대입해서는안된다.

 

        typename xiterator_traits<T>::value_type s = *first;

 

        while ( ++first != last )

        {

               s = s + *first;

        }

        return s;

}

 

void main()

{

        int x[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

        int n2 = sum( x, x+10 );

 

        slist<int> s;

 

        s.push_front( 10 );

        s.push_front( 20 );

        s.push_front( 30 );

        s.push_front( 40 );

 

        //slist안에있는모든요소의합을구하고싶다.

        int k = sum( s.begin(), s.end() );

 

        cout << k << endl;

}


////////////////////////////////////////////////////////////////////
// iterator_category 의 구현
template<typename T> struct xiterator_traits

{

        typedef typename T::value_type value_type;

        typedef typename T::iterator_category iterator_category;

};

 

// template 부분전문화( 포인터로되어있는것)

template<typename T> struct xiterator_traits<T*>

{

        typedef T value_type;

        typedef random_access_iterator_tag   iterator_category;

};

 

//임의접근일경우

template<typename T> void xadvance(T& p, int n ,random_access_iterator_tag)

{

        p += n;

}

 

template<typename T>

void xadvance( T& p, int n )

{

        xadvance( p, n, xiterator_traits<T>::iterator_category() );

}

 

void main()

{

        int x[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

 

        int *p = x;

 

        xadvance( p, 3 );   // p의반복자를3만큼전진해야한다. p+n 처리를하자.

 

        cout << *p << endl;    // 4이나와야한다.

}

Tag |

Trackback Address :: 이 글에는 트랙백을 보낼 수 없습니다